R - 正则表达式匹配模式并仅存储新列中的模式?

时间:2017-01-10 00:44:55

标签: r regex

我一直在寻找几个小时。这应该很容易,但我不明白:(

我有一个名为ds的数据框,其中包含一个结构如下的列:

name
"Doe, Mr. John"
"Worth, Miss. Jane"

我想提取中间词并将其放入新列中。

#This is how I'm doing it now
ds$title <- NA

mr  <- grep(", Mr. ", ds$name)
miss <- grep(", Miss. ", ds$name)

ds$title[mr] <- ", Mr. "
ds$title[miss] <- ", Miss. "

我正在尝试用正则表达式来概括它,这样它就可以使任何中间词匹配“逗号空格词句点空间”的模式

这是我最好的猜测,但它只删除了模式:

gsub(", .+\\.+ ", "", ds$name)

如何保留模式并删除其余模式?

谢谢!

2 个答案:

答案 0 :(得分:3)

您可以使用捕获组。基本上,您匹配整个模式,使用捕获组来匹配您要保留的部分,并将整个匹配替换为捕获组:

# I often specify perl = TRUE, though it isn't necessary here
(ds$title <- gsub(".+(, .+\\.+ ).+", "\\1", ds$name, perl = TRUE))
#[1] ", Mr. "   ", Miss. "

捕获组是括号中的内容((, .+\\.+ )),您可以使用\\1返回它。如果您有第二个捕获组,则将其称为\\2

请注意,如果要捕获逗号,空格,单词,句点,空格,则可以将捕获组修改为(, .+\\. )。您只需要匹配一个句点,而不是一个或多个句号。

不使用捕获组的简单stringi替代方法是stri_extract_first_regex(或者在这种情况下stri_extract_last_regexstri_extract_all_regex正常工作)

library(stringi)
ds$title <- stri_extract_first_regex(ds$name, ", .+\\. ")
#[1] ", Mr. "   ", Miss. "

正如thelatemail在评论中指出的那样,你也可以对基础R做类似的事情,但是要记住如何使用regmatchesregexpr函数要困难得多:

regmatches(ds$name, regexpr(", .+\\. ", ds$name))
#[1] ", Mr. "   ", Miss. "

答案 1 :(得分:1)

匹配的捕获组是您的BFF:

library(stringi)
library(purrr)

ds <- data.frame(name=c("Doe, Mr. John", "Worth, Miss. Jane"), stringsAsFactors=FALSE)

nonsp <- "[[:alnum:][:punct:]]+"
sp <- "[[:blank:]]+"

stri_match_all_regex(ds$name, nonsp %s+% sp %s+% "(" %s+% nonsp %s+% ")" %s+% sp %s+% nonsp) %>%
  map_chr(2)
## [1] "Mr."   "Miss."

为您的&#34;添加列到数据框&#34;需要:

library(stringi)
library(dplyr)
library(purrr)

ds <- data.frame(name=c("Doe, Mr. John", "Worth, Miss. Jane"), stringsAsFactors=FALSE)

nonsp <- "[[:alnum:][:punct:]]+"
sp <- "[[:blank:]]+"

mutate(ds, title=stri_match_all_regex(ds$name, nonsp %s+% sp %s+% "(" %s+% nonsp %s+% ")" %s+% sp %s+% nonsp) %>% map_chr(2))
##                name title
## 1     Doe, Mr. John   Mr.
## 2 Worth, Miss. Jane Miss.