【发布时间】:2016-11-13 15:30:05
【问题描述】:
从关闭的this question,操作员询问如何从字符串中提取排名、第一、中间和最后
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] - 我认为这些不会起作用,因为提出了另一种模式而不是回答问题。此外,在此示例中,排名中的单词数量是任意的,匹配排名的模式也适用于名字。
【问题讨论】:
-
this demo 是预期的结果吗? (
perl=TRUE) -
好吧,我认为这仍然不适用于像
Deputy Sheriff John Gooch这样的 str ,如果有 4 个单词,如何区分。 -
如果你需要这个,你需要一个标题列表
-
@bobblebubble 是的,这似乎可行,我从未使用过
?|,所以您仍然需要定义可能的替代方案(例如,其他示例,这里只有两个)?并且没有全局标志从头开始并反向运行?在 rpat <- '(?|(?<rank>\\w+) (?<first>\\w+)(?<middle>) (?<last>\\w+)$|(?<rank>[\\w ]+) (?<first>\\w+) (?<middle>[\\w.]+) (?<last>\\w+))'; do.call('rbind', Map(f, x, pat)) -
@rawr 这是一个branch reset,用替代品维护组索引。