我试图在特定字符串后提取一定数量的单词。
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个单词中的任何一个,但怀疑这是否是你真正需要的。