匹配模式,只要它不包含特定字符串

Match pattern so long as it doesn't contain a specific string

假设我有以下字符串:

quiz.1.player.chat_resultspartner_quiz.1.player.chat_results

我有数百个这样的字符串,唯一的区别是一个带有前缀 "partner" 而另一个没有。我正在尝试匹配一个而不是另一个。

我想要匹配的特定模式如下所示:

index <- grep('^(quiz.)[1-5]{1}.player.chat_results', names(data))

但这将匹配两个字符串。我猜我必须像这样使用一些负面的前瞻性:

^((?!partner).) 

但我不确定在哪里使用它。

我们可以使用两个 grepl 以避免混淆

grepl('quiz', names(data)) & !grepl('partner', names(data))
#[1]  TRUE FALSE

对于有点像我regex-blind的人,sub可以提供帮助,

sub('_.*', '', x) == 'partner'
#[1]  TRUE FALSE

我会回答你的标题问题,因为这对其他人找到这个问题最有用。

如何匹配包含给定模式的字符串?很简单,匹配模式并反转它。

index <- grep('^partner', names(data), invert = TRUE)

如果你想匹配包含数字的模式,你可以使用一个单词边界 \b 后跟一个否定前瞻 (?!partner) 来断言直接在右边的不是伙伴。

注意转义点以字面匹配,可以省略{1}。如果你不是围绕测验捕获的群体的价值,你也可以省略它。

要匹配字符串的其余部分,您可以使用 \S+ 来匹配非空白字符。

\b(?!partner)quiz\.[1-5]\.player\S*

Regex demo | R demo

例如

regmatches(txt1,regexpr("\b(?!partner)quiz\.[1-5]\.player\S*",txt, per=TRUE))

另一种方法:使用来自 stringr

str_detect
> library(stringr)
> str_detect(string, "partner", negate=TRUE)
[1]  TRUE FALSE

你甚至可以使用一个 grepl 并否定结果

> !grepl("partner", string)
[1]  TRUE FALSE

只是为了好玩:您可以使用 \._ 作为分隔符拆分字符串,然后遍历结果列表中的每个元素,将每个元素与 partner 进行比较,最后反转结果

> sapply(strsplit(string, "\.|_"), function(x) !"partner" %in%  x)
[1]  TRUE FALSE