如何匹配具有"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)
是不正确的。
对于负展望,您可以使用如下内容:
bfoob(?!W+bar)
正则表达式 101 演示。
显然,如果在 R 中是非法的,则需要对其进行转义,因此您将改用
\bfoo\b(?!\W+bar)
。
如果bar
也必须是整个单词,则可以在末尾添加额外的b
:
bfoob(?!W+barb)
另一个演示。
在一般情况下,要检测是否存在不跟bar
foo
(foo
右侧的任何位置(,您可以将基本 Rgrep
与perl=TRUE
参数一起使用:
x <- c("foo bar", "foo")
grep("(?s)foo(?!.*bar)", x, perl=TRUE, value=TRUE)
查看 R 演示
(?!.*bar)
是一个负面的展望。它只断言在当前正则表达式引擎位置之后缺少某种模式,即如果没有匹配项,它会检查并返回 true,否则返回 false。因此,它不会"消耗"字符,正则表达式引擎保持在输入字符串中的相同位置。在此正则表达式中,它是foo
之后的位置。因此,在foo
之后,正则表达式引擎开始查找.*
(包括换行符的任何字符(由于DOTALL
(?s)
内联修饰符(,0 或更多重复(,然后尝试匹配bar
。因此,如果有bar
,将没有匹配,因为前瞻将返回false。
为了将这些单词匹配为整个单词,不要忘记模式中每个单词的两端b
(正如艾哈迈德在他的回答中指出的那样(。
注意:如果foo
和bar
之间只能有一组特定的字符,请使用特定模式而不是.*
:
foo(?!s+bar) - no "bar" after "foo" separated with 1+ whitespaces from it
foo(?!W+bar) - no "bar" after "foo" separated with 1+ non-word chars from it
foo(?!w*bar) - no "bar" after "foo" in the same "word" (digits, letters, _)
foo(?!p{L}*bar) - no "bar" after "foo" in the same letter-word
是的,不要忘记在 R 代码中使用双转义反斜杠。