stringr:提取包含特定词汇的单词

3

考虑这个简单的例子

dataframe <- data_frame(text = c('WAFF;WOFF;WIFF200;WIFF12',
                                 'WUFF;WEFF;WIFF2;BIGWIFF'))

> dataframe
# A tibble: 2 x 1
                      text
                     <chr>
1 WAFF;WOFF;WIFF200;WIFF12
2  WUFF;WEFF;WIFF2;BIGWIFF

我想提取包含WIFF的单词,最终得到如下数据框:

> output
# A tibble: 2 x 1
            text
           <chr>
1 WIFF200;WIFF12
2  WIFF2;BIGWIFF

我尝试使用

dataframe %>% 
  mutate( mystring = str_extract(text, regex('\bwiff\b', ignore_case=TRUE)))

但是这只返回了NA。有什么想法吗?
谢谢!
2个回答

4

一个经典的、非正则表达式的 R 语言方法是:

sapply(strsplit(me$text, ';', fixed = TRUE), function(i) 
                              paste(grep('WIFF', i, value = TRUE, fixed = TRUE), collapse = ';'))

#[1] "WIFF200;WIFF12" "WIFF2;BIGWIFF" 

2

您似乎想要删除所有包含WIFF和结尾的;(如果有)的单词。请使用

> dataframedataframe <- data.frame(text = c('WAFF;WOFF;WIFF200;WIFF12', 'WUFF;WEFF;WIFF2;BIGWIFF'))
> dataframe$text <- str_replace_all(dataframe$text, "(?i)\\b(?!\\w*WIFF)\\w+;?", "")
> dataframe
            text
1 WIFF200;WIFF12
2  WIFF2;BIGWIFF

模式(?i)\\b(?!\\w*WIFF)\\w+;?匹配:

  • (?i) - 不区分大小写的内联修饰符
  • \\b - 单词边界
  • (?!\\w*WIFF) - 负预测,在单词中包含 WIFF 时失败任何匹配
  • \\w+ - 1个或多个单词字符
  • ;? - 可选的 ; (? 匹配它所修改的模式的1个或0个出现次数)

如果您想使用 str_extract,请注意您的正则表达式可能无法工作,因为\bWIFF\b 匹配完整单词 WIFF,而且没有在您的DF中找到这样的单词。您可以使用"(?i)\\b\\w*WIFF\\w*\\b"不区分大小写地匹配包含 WIFF 的任何单词,并使用 str_extract_all 获取多个匹配项,不要忘记将匹配项连接成单个 "字符串":

> df <- data.frame(text = c('WAFF;WOFF;WIFF200;WIFF12', 'WUFF;WEFF;WIFF2;BIGWIFF'))
> res <- str_extract_all(df$text, "(?i)\\b\\w*WIFF\\w*\\b")
> res
[[1]]
[1] "WIFF200" "WIFF12" 

[[2]]
[1] "WIFF2"   "BIGWIFF"

> df$text <- sapply(res, function(s) paste(s, collapse=';'))
> df
            text
1 WIFF200;WIFF12
2  WIFF2;BIGWIFF

您可以通过将str_extract_all放入sapply函数中来“缩小”代码,我将它们分开以获得更好的可读性。


谢谢Wiktor,非常好的建议。您似乎暗示替换不匹配的模式比提取匹配的模式更容易?为什么? - ℕʘʘḆḽḘ
1
@Noobie:我没有说过那个。你可以自己决定哪个更容易。 - Wiktor Stribiżew
我的意思是你的解决方案很好,但是你知道我的 str_extract 根本不起作用吗? - ℕʘʘḆḽḘ
1
@Noobie:我的逻辑很简单:如果您的字符向量包含不一定包含“WIFF”的“单词”,那么匹配方法意味着拆分/提取或匹配所有有效出现,然后将它们重新连接。对我来说看起来很麻烦(尽管这不是我写答案时的想法)。您的方法可能行不通,因为\bWIFF\b匹配整个单词WIFF,而且没有其他内容。您的DF中没有这样的单词。 - Wiktor Stribiżew
好的,明白了,谢谢。你觉得在这里使用 str_extract 有什么简单的方法吗?我只是想学习一些正则表达式技巧 :) - ℕʘʘḆḽḘ
1
我忘记让模式不区分大小写了,现在已经添加了这一部分。 - Wiktor Stribiżew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接