匹配“foo”的实例后面没有“bar”

时间:2018-05-22 02:46:37

标签: r regex

如何匹配“foo”后跟“bar”以外的字符串的字符串(foo末尾带有字边界)?

实施例

library(stringr)
str_detect("foo 123", "\\bfoo\\b^(bar)")  # should be TRUE
str_detect("foo", "\\bfoo\\b^(bar)")  # should be TRUE
str_detect("foo bar", "\\bfoo\\b^(bar)")  # should be FALSE

显然我尝试过,\\bfoo\\b^(bar)不正确。

2 个答案:

答案 0 :(得分:2)

使用负面Lookahead,您可以使用以下内容:

\bfoo\b(?!\W+bar)

Regex101 demo

显然,如果\在R中是非法的,则您需要将其撤消,因此您需要使用\\bfoo\\b(?!\\W+bar)

如果bar也必须是一个完整的词,您可以在最后添加额外的\b

\bfoo\b(?!\W+bar\b)

Another demo

答案 1 :(得分:0)

在一般情况下,要检测foo是否存在barfoo右侧的任何位置),您可以使用基数R {{1}使用grep参数:

perl=TRUE

请参阅R demo

x <- c("foo bar", "foo") grep("(?s)foo(?!.*bar)", x, perl=TRUE, value=TRUE) negative lookahead。它只声明在当前正则表达式引擎位置之后缺少某些模式,即如果没有匹配则检查并返回true,否则返回false。因此,它不会消费&#34;字符,正则表达式引擎停留在输入字符串中的相同位置。在这个正则表达式中,它是(?!.*bar)之后的位置。因此,在foo之后,正则表达式引擎开始查找foo(包含换行符的任何字符(由于.* DOTALL内联修饰符),0或更多重复) ,然后尝试匹配(?s)。因此,如果有bar,则不会匹配,因为前瞻将返回 false

要将这些单词作为整个单词进行匹配,请不要忘记模式中每个单词两端的bar(正如Ahmed在答案中所指出的那样)。

注意:如果\bfoo之间只有一组特定字符,请使用特定模式而不是bar

.*

是的,不要忘记在R代码中双重转义反斜杠。