用于匹配未跟随某个其他子字符串的子字符串的正则表达式

时间:2010-04-13 15:48:30

标签: java regex clojure

我需要一个匹配blahfooblah但不匹配blahfoobarblah

的正则表达式

我希望它只匹配foo和foo周围的所有内容,只要它后面没有bar。

我尝试使用此foo.*(?<!bar),它非常接近,但它匹配blahfoobarblah。背后的负面看法需要匹配任何东西而不仅仅是酒吧。

我使用的特定语言是Clojure,它使用Java正则表达式。

编辑:更具体地说,我还需要它传递blahfooblahfoobarblah而不是blahfoobarblahblah

5 个答案:

答案 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之后的任何字符,包括字符。