R - 正则表达式匹配模式,并仅将模式存储在新列中



我已经搜索了几个小时。这应该很容易,但我看不出如何:(

我有一个名为 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)

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

谢谢!

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

# 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在评论中指出的那样,您也可以使用base R做类似的事情,但是记住如何使用regmatchesregexpr函数有点困难:

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

匹配的捕获组是您的 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."

对于"向数据框添加列"的需求:

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.

最新更新