我一直在寻找几个小时。这应该很容易,但我不明白:(
我有一个名为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)
如何保留模式并删除其余模式?
谢谢!
答案 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_regex
或stri_extract_all_regex
正常工作)
library(stringi)
ds$title <- stri_extract_first_regex(ds$name, ", .+\\. ")
#[1] ", Mr. " ", Miss. "
正如thelatemail在评论中指出的那样,你也可以对基础R做类似的事情,但是要记住如何使用regmatches
和regexpr
函数要困难得多:
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.