我需要一个匹配blahfooblah
但不匹配blahfoobarblah
我希望它只匹配foo和foo周围的所有内容,只要它后面没有bar。
我尝试使用此foo.*(?<!bar)
,它非常接近,但它匹配blahfoobarblah
。背后的负面看法需要匹配任何东西而不仅仅是酒吧。
我使用的特定语言是Clojure,它使用Java正则表达式。
编辑:更具体地说,我还需要它传递blahfooblahfoobarblah
而不是blahfoobarblahblah
。
答案 0 :(得分:127)
/(?!.*bar)(?=.*foo)^(\w+)$/
blahfooblah # pass
blahfooblahbarfail # fail
somethingfoo # pass
shouldbarfooshouldfail # fail
barfoofail # fail
NODE EXPLANATION
--------------------------------------------------------------------------------
(?! look ahead to see if there is not:
--------------------------------------------------------------------------------
.* any character except \n (0 or more times
(matching the most amount possible))
--------------------------------------------------------------------------------
bar 'bar'
--------------------------------------------------------------------------------
) end of look-ahead
--------------------------------------------------------------------------------
(?= look ahead to see if there is:
--------------------------------------------------------------------------------
.* any character except \n (0 or more times
(matching the most amount possible))
--------------------------------------------------------------------------------
foo 'foo'
--------------------------------------------------------------------------------
) end of look-ahead
--------------------------------------------------------------------------------
^ the beginning of the string
--------------------------------------------------------------------------------
( group and capture to \1:
--------------------------------------------------------------------------------
\w+ word characters (a-z, A-Z, 0-9, _) (1 or
more times (matching the most amount
possible))
--------------------------------------------------------------------------------
) end of \1
--------------------------------------------------------------------------------
$ before an optional \n, and the end of the
string
如果您只想在bar
之后直接排除foo
,则可以使用
/(?!.*foobar)(?=.*foo)^(\w+)$/
您对问题进行了更新,以使其具体化。
/(?=.*foo(?!bar))^(\w+)$/
fooshouldbarpass # pass
butnotfoobarfail # fail
fooshouldpassevenwithfoobar # pass
nofuuhere # fail
(?=.*foo(?!bar))
确保找到foo
但未直接跟踪bar
答案 1 :(得分:44)
要匹配foo
以下不属于bar
的内容,请尝试
foo(?!bar)
您的带有负面反馈的版本实际上是“匹配foo
后跟不会以bar
结尾的内容”。 .*
匹配barblah
的所有内容,而(?<!bar)
会回顾lah
,并检查它与bar
不匹配,而不是{{1}}所以整个模式都匹配。
答案 2 :(得分:2)
改为使用负面预测:
\s*(?!\w*(bar)\w*)\w*(foo)\w*\s*
这对我有用,希望它有所帮助。祝你好运!
答案 3 :(得分:1)
你写了一条评论,建议你这样做是为了匹配字符串中的所有单词而不是整个字符串本身。
我没有在评论中混淆所有这些,而是将其作为新答案发布。
/(?=\w*foo(?!bar))(\w+)/
foowithbar fooevenwithfoobar notfoobar foohere notfoobarhere butfooisokherebar notfoobarhere andnofuu needsfoo
foowithbar fooevenwithfoobar foohere butfooisokherebar needsfoo
答案 4 :(得分:0)
您的特定匹配请求可以通过以下方式匹配:
\w+foo(?!bar)\w+
这将匹配blahfooblahfoobarblah
但不匹配blahfoobarblahblah
。
foo.*(?<!bar)
正则表达式的问题是.*
之后的foo
。它匹配bar
之后的任何字符,包括字符。