在R中的字符串后提取一定数量的单词或特殊字符



我试图在特定字符串后提取一定数量的单词。

library(stringr)
x <- data.frame(end = c("source: from animal origin as Vitamin A / all-trans-Retinol: Fish in general, liver and dairy products;", "source: Eggs, liver, certain fish species such as sardines, certain mushroom species such as shiitake", "source: Leafy green vegetables such as spinach; egg yolks; liver"))

例如,提取"0"后面的4个单词;源";,我从另一个问题中学到了使用这个代码:

trimws(stringr::str_extract(x$end, '(?<=source:\s)(\w+,?\s){4}'))

这非常有效,然而,如果我试着选择8个单词,我注意到它不识别"/"并且对于第一字符串返回NA。

trimws(stringr::str_extract(x$end, '(?<=source:\s)(\w+,?\s){8}'))

问题是:是否有包含特殊字符(或绕过它们(的正则表达式,这样我仍然可以提取所需的单词?我注意到其他字符(例如-(或双空格也会发生同样的情况。

8个单词的预期输出应该是这样的:

from animal origin as Vitamin A / all-trans-Retinol  

它是否将/和-算作单词并不重要,因为我总是可以将量词的数量调整为更多(在我的情况下,我不介意提取超出我需要的数量(。

谢谢

您可以依赖与任何非空白字符匹配的S简写字符类:

(?<=source:s)S+(?:s+S+){3,7}b

请参阅regex演示。详细信息:

  • (?<=source:s)-紧跟在source:前面的位置和空白
  • S+-一个或多个非空白字符
  • (?:s+S+){3,7}-出现三到七个1+空白字符,然后出现1+非空白字符
  • b-一个单词边界

在线查看R演示:

library(stringr)
x <- data.frame(end = c("source: from animal origin as Vitamin A / alltrans-Retinol: Fish in general, liver and dairy products;", "source: Eggs, liver, certain fish species such as sardines, certain mushroom species such as shiitake", "source: Leafy green vegetables such as spinach; egg yolks; liver"))
stringr::str_extract(x$end, "(?<=source:\s)\S+(?:\s+\S+){3,7}\b")

输出:

[1] "from animal origin as Vitamin A / alltrans-Retinol"
[2] "Eggs, liver, certain fish species such as sardines"
[3] "Leafy green vegetables such as spinach; egg yolks" 

以下是使用regmatches+gsub的基本R选项

lapply(regmatches(u <- gsub(".*?source:\s+?","",x$end),gregexpr("\w+",u)),`[`,1:4)

它给出

[[1]]
[1] "from"   "animal" "origin" "as"
[[2]]
[1] "Eggs"    "liver"   "certain" "fish"
[[3]]
[1] "Leafy"      "green"      "vegetables" "such"

我们可以用{4,8}指定范围

trimws(stringr::str_extract(x$end, '(?<=source:\s)(\w+,?\s){4,8}'))

或者,如果需要特定的数字,则使用这些数字进行循环

pat <- sprintf('(?<=source:\s)(\w+,?\s){%d}', c(8, 4))

然后提取具有该模式和CCD_ 10 的单词

library(dplyr)
do.call(coalesce, lapply(pat, function(y) trimws(stringr::str_extract(x$end, y))))
#[1] "from animal origin as"     
#[2] "Eggs, liver, certain fish species such as sardines,"
#[3] "Leafy green vegetables such"  

问题是:是否有一个regex来包含特殊字符(或绕过它们(,这样我仍然可以提取所需的单词?我注意到其他字符(例如-(或双空格也会发生同样的情况。

侧节点:这是一种XY问题(https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)

你的问题不是正则表达式不起作用——你的问题是正则表达式起作用,但你期望有所不同。你可以用它来选择某个字符串后面即将出现的8个单词,但在非单词(/(之前只有6个单词,所以这与你的模式不匹配。

因此,为了提供一个";回答";对于你的问题,你应该先重做你的问题:

你的确切期望是什么?

akrun的解决方案可以匹配4-8个单词中的任何一个,但怀疑这是否是你真正需要的。

最新更新