代码之家  ›  专栏  ›  技术社区  ›  Rayne

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

  •  85
  • Rayne  · 技术社区  · 14 年前

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

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

    我试着用这个: foo.*(?<!bar) 很接近,但很匹配 布拉夫巴布拉 . 后面的负面表情需要匹配任何东西,而不仅仅是酒吧。

    我使用的特定语言是Culjule,它在引擎盖下使用Java正则表达式。

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

    5 回复  |  直到 8 年前
        1
  •  118
  •   maček    14 年前

    尝试:

    /(?!.*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)) 确保一个 找到但没有直接跟踪 酒吧

        2
  •  43
  •   stevemegson    14 年前

    匹配一个 foo 跟着一些不起眼的东西 bar 尝试

    foo(?!bar)
    

    你的版本带有否定的lookbehind实际上是“match a 然后是一些没有结束的事情 酒吧 “。这个 .* 匹配所有 barblah (?<!bar) 回头看 lah 检查是否不匹配 酒吧 ,但它没有,所以整个模式都匹配。

        3
  •  2
  •   Audie    14 年前

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

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

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

        4
  •  1
  •   maček    14 年前

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

    我并没有在评论中把所有这些都混为一谈,而是将其作为一个新的答案发布。

    新正则表达式

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

    样本文本

    有吧台的有吧台的有吧台的没有吧台的有吧台的没有吧台的有吧台的但是有吧台的没有吧台的没有吧台的和没有需要的

    比赛

    有吧台的有吧台的有吧台的有吧台的但有吧台的需要

        5
  •  0
  •   dawg    14 年前

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

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

    这将匹配 blahfooblahfoobarblah 但不是 blahfoobarblahblah .

    你的regex的问题 foo.*(?<!bar) .* 之后 foo . 它匹配任意多个字符,包括后面的字符 bar .