从字符串中仅提取特定单词

时间:2018-09-05 08:00:56

标签: regex substring

我有美国总统名单,上面有关于各种主题的演讲(尽管有些没有标签),在文件名栏中,我有类似

的格式

1981_Reagan, 1982_economy_Reagan... 1994_Clinton, 1994_criminal_justice_Clinton

(每行单独),我想摘录哪个总统讲话。我打算使用类似sub_str之类的函数,但不确定如何提取名称-显然,要考虑名称的不同长度,但又不想提取不需要的信息,例如年份或其他话。

3 个答案:

答案 0 :(得分:2)

这是使用strsplit的一种简单方法,假设行长名称始终位于字符串的末尾,并以“ _”分隔所有内容:

vec <- c("1981_Reagan",
         "1982_economy_Reagan",
         "1994_Clinton",
         "1994_criminal_justice_Clinton")
sapply(strsplit(vec, "_"), function(x) x[length(x)])
#output
"Reagan"  "Reagan"  "Clinton" "Clinton"

基本上用“ _”分割字符串,并从每个结果向量中提取最后一个元素

使用正则表达式的另一种方法:

sub(".+_", "", vec)

将所有不超过_的字符替换为空。这是贪婪的,因此它将替换到最后一个_

答案 1 :(得分:0)

您还可以:

vec <- c("1981_Reagan",
         "1982_economy_Reagan",
         "1994_Clinton",
         "1994_criminal_justice_Clinton")

sub(".*_(\\w+)","\\1",vec,perl=T)

#[1] "Reagan"  "Reagan"  "Clinton" "Clinton"

使用Perl,我的解决方案似乎是最快的。

vec <- c("1981_Reagan",
         "1982_economy_Reagan",
         "1994_Clinton",
         "1994_criminal_justice_Clinton")

vec <- rep(vec,99999)

f1 <- function(vec) {sub(".*_", "", vec)}

f2 <- function(vec) {sub(".*_(\\w+)","\\1",vec,perl=T)}

f3 <- function(vec) {gsub(".+_", "", vec)}

microbenchmark::microbenchmark( f1(vec), f2(vec), f3(vec),times=100)

#Unit: milliseconds
#    expr      min       lq     mean   median       uq      max neval cld
# f1(vec) 212.8052 213.9725 215.5334 215.1973 216.5564 222.4681   100  b 
# f2(vec) 133.7839 134.6375 136.0296 135.0752 136.3612 142.8160   100 a  
# f3(vec) 290.8456 293.4051 295.5549 294.5525 295.5341 338.8277   100   c

答案 2 :(得分:0)

在示例输入中,至少有一个规律是总统的姓名(并且只有他们的姓名)大写。

您可以利用它...

library(stringr)
str_extract(original_string, "(?<=_)[A-Z][^_]+")
[1] "Reagan"  "Reagan"  "Clinton" "Clinton"

哪里

original_string <- c(
  "1981_Reagan", 
  "1982_economy_Reagan", 
  "1994_Clinton", 
  "1994_criminal_justice_Clinton"
)