从关闭的this question中,运算符(operator)询问如何从字符串中提取排名,首位,中间和最后一位

x <- c("Marshall Robert Forsyth", "Deputy Sheriff John A. Gooch",
       "Constable Darius Quimby", "High Sheriff John Caldwell Cook")

#                                  rank             first    middle      last
# Marshall Robert Forsyth          "Marshall"       "Robert" ""          "Forsyth"
# Deputy Sheriff John A. Gooch     "Deputy Sheriff" "John"   "A."        "Gooch"
# Constable Darius Quimby          "Constable"      "Darius" ""          "Quimby"
# High Sheriff John Caldwell. Cook "High Sheriff"   "John"   "Caldwell"  "Cook"

我想出了这个方法,只有在中间名包含句点的情况下,它才有效。否则,排名模式会从行开始处捕获尽可能多的内容。
pat <- '(?i)(?<rank>[a-z ]+)\\s(?<first>[a-z]+)\\s(?:(?<middle>[a-z.]+)\\s)?(?<last>[a-z]+)'

f <- function(x, pattern) {
  m <- gregexpr(pattern, x, perl = TRUE)[[1]]
  s <- attr(m, "capture.start")
  l <- attr(m, "capture.length")
  n <- attr(m, "capture.names")
  setNames(mapply('substr', x, s, s + l - 1L), n)
}

do.call('rbind', Map(f, x, pat))

#                                 rank                first      middle last
# Marshall Robert Forsyth         "Marshall"          "Robert"   ""     "Forsyth"
# Deputy Sheriff John A. Gooch    "Deputy Sheriff"    "John"     "A."   "Gooch"
# Constable Darius Quimby         "Constable"         "Darius"   ""     "Quimby"
# High Sheriff John Caldwell Cook "High Sheriff John" "Caldwell" ""     "Cook"

因此,如果中间名没有给出或包含句点,这将起作用
x <- c("Marshall Robert Forsyth", "Deputy Sheriff John A. Gooch",
       "Constable Darius Quimby", "High Sheriff John Caldwell. Cook")
do.call('rbind', Map(f, x, pat))

所以我的问题是,有没有一种方法可以从字符串的末尾开始对匹配进行优先级排序,以使该模式匹配最后,中间,第一个,然后将所有其他内容排在排名之前。

我能做到这一点而无需反转字符串或类似的东西吗?另外,也许有更好的模式,因为我对正则表达式不太满意。

相关-[1] [2]-我认为这些方法不起作用,因为建议了另一种模式而不是回答问题。同样,在此示例中,等级中的单词数是任意的,并且与等级匹配的模式也适用于名字。

最佳答案

我们不能从头开始匹配,在我知道的任何正则表达式系统中都没有针对它的修饰符。但是我们可以检查到底有多少个单词,并限制我们的贪婪:)。下面的正则表达式正在执行此操作。

这将满足您的要求:

^(?<rank>(?:(?:[ \t]|^)[a-z]+)+?)(?!(?:[ \t][a-z.]+){4,}$)[ \t](?<first>[a-z]+)[ \t](?:(?<middle>[a-z.]+)[ \t])?(?<last>[a-z]+)$

Live preview in regex101.com

r - 从字符串末尾开始匹配-LMLPHP

还有一个异常(exception):

当您的排名具有“第一”,“最后”和超过1个单词时,排名的一部分将成为“名字”。

r - 从字符串末尾开始匹配-LMLPHP

为了解决这个问题,您必须定义一个等级前缀列表,这意味着后面肯定还有另一个单词并以贪婪的方式捕获它。

例如:副手,高级。

关于r - 从字符串末尾开始匹配,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40575516/

10-16 20:43