一个正则表达式,用于匹配没有其他子字符串的子字符串


115

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

我希望它只匹配foo和foo周围的所有内容,只要不跟在bar后面即可。

我尝试使用此方法:foo.*(?<!bar)这是相当接近的,但它匹配blahfoobarblah。负面的眼光需要匹配任何东西,而不仅仅是障碍。

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

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


1
您是否尝试使用foo。*(?<!bar。*)吗?
Thibault Falise 2010年

Answers:


158

尝试:

/(?!.*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找到a ,但不直接遵循bar


这是非常接近的,也是很好的答案。我知道我不够具体。:(我需要这样的:“blahfoomeowwoof / foob​​ar的/”通过,因为寂寞“富”,但不是这个blahfoobarmeowwoof的如果这是可能的。
莱恩

附带的问题是,如何匹配“机器人”而不是“机器人”?
雷恩2010年

是。我可以使用我现在拥有的东西,但是如果我只匹配bot但不匹配botters,它将更容易。我非常抱歉。我对正则表达式没有经验,恐怕我正在慢慢弄清楚自己想要什么。:p
Rayne

1
@Rayne,这是同样的问题。在上面的示例中,您想匹配foo但不匹配foobar。要匹配bot但不匹配botters,您可以使用/(?=.*bot(?!ters))^(\w+)$/
maček

好吧,我通常是针对整个单词。就像我说的那样,我对自己真正想要的和真正可能的感到困惑。这样做是可行的。谢谢您的时间。:)
Rayne 2010年

55

要使foo跟随者与不以开头的事物匹配bar,请尝试

foo(?!bar)

您的后向否定版本实际上是“匹配foo后跟不以结尾的内容bar”。本.*场比赛所有的barblah,和(?<!bar)长相背部lah,并检查不匹配bar,它没有,所以整个模式匹配。


因此,我尝试使用一种正则表达式,该表达式旨在匹配字符串“ did you”(只要不跟“ say”)。例如,当区分“您说了”和“您想过”时,它就起作用了,但是仅“您做了”本身并没有被捕获,它应该被捕获。有什么建议?
soosus

2

请改用否定的前瞻:

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

这对我有用,希望对您有所帮助。祝好运!


简单而有效的正则表达式,也可用于排除重复的字符串(“ foofoo”)。完善!
乔纳斯·比斯特伦2014年

1

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

与其将所有这些内容混在一起,不如将其发布为新答案。

新正则表达式

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

示例文本

foowithbar fooevenwithfoobar notfoobar foohere notfoobarhere butfooisokherebar notfoobarhere andnofuu needsfoo

火柴

foowithbar fooevenwithfoobar foohere butfooisokherebar needsfoo


0

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

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

这将匹配blahfooblahfoobarblah但不匹配blahfoobarblahblah

正则表达式的问题foo.*(?<!bar).*after foo。它与任意多个字符匹配,包括之后的字符bar

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.