一个正则表达式来匹配一个后面没有其他子字符串的子字符串

我需要一个匹配 blahfooblah但不是 blahfoobarblah的正则表达式

我希望它只匹配 foo 和 foo 周围的所有东西,只要它后面没有酒吧。

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

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

编辑: 更具体地说,我也需要它通过 blahfooblahfoobarblah,但不是 blahfoobarblahblah

111235 次浏览

Try:

/(?!.*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

其他正则表达式

如果只想在 foo之后排除 bar,可以使用

/(?!.*foobar)(?=.*foo)^(\w+)$/

剪辑

你更新了你的问题,使它具体。

/(?=.*foo(?!bar))^(\w+)$/

新的测试

fooshouldbarpass               # pass
butnotfoobarfail               # fail
fooshouldpassevenwithfoobar    # pass
nofuuhere                      # fail

新的解释

(?=.*foo(?!bar))确保找到 foo,但不直接跟踪 bar

用消极的眼光来看待未来:

\s*(?!\w*(bar)\w*)\w*(foo)\w*\s*

这招对我很管用,希望能有帮助,祝你好运!

若要匹配 foo后跟一个不以 bar开头的内容,请尝试

foo(?!bar)

您的负向后看版本实际上是“匹配 foo后跟不以 bar结尾的内容”。.*匹配所有的 barblah,而 (?<!bar)回头查看 lah并检查它是否匹配 bar,它确实不匹配,所以整个模式都匹配。

您的特定匹配请求可以通过以下方式进行匹配:

\w+foo(?!bar)\w+

这将匹配 blahfooblahfoobarblah,但不匹配 blahfoobarblahblah

foo.*(?<!bar)的正则表达式的问题在于 foo之后的 .*。它匹配包括 bar之后的字符在内的所有字符。

你写了一个评论,建议你喜欢这样匹配字符串中的所有单词,而不是整个字符串本身。

与其在评论中混合所有这些,我更愿意把它作为一个新的答案发布出去。

新的正则表达式

/(?=\w*foo(?!bar))(\w+)/

示例文本

这里没有脚,这里没有脚,这里没有脚,这里没有脚,这里没有足

火柴

这里有足够的足够的足够的足够的足够的足够的足够的足够的足够的足够的足够的足够的足够的足够的足够的足够