【问题标题】:Regex for matching something if it is not preceded by something else用于匹配某物(如果它前面没有其他东西)的正则表达式
【发布时间】:2022-12-23 02:41:45
【问题描述】:

使用 Java 中的正则表达式,我想编写一个正则表达式,当且仅当模式前面没有某些字符时才会匹配。例如:

String s = "foobar barbar beachbar crowbar bar ";

如果 bar 前面没有 foo,我想匹配。所以输出将是:

barbar
beachbar
crowbar
bar

【问题讨论】:

    标签: java regex


    【解决方案1】:

    你想像这样使用negative lookbehind

    w*(?<!foo)bar
    

    (?&lt;!x) 的意思是“只有在这一点之前没有“x””。

    有关详细信息,请参阅Regular Expressions - Lookaround

    编辑: 添加 w* 以捕获之前的字符(例如“海滩”)。

    【讨论】:

    • 需要做哪些修改才能不匹配 foo_arbitrary_bar?即 foo 不是紧接在 bar 之前
    • @BradKent (?&lt;!foo).*bar 会匹配类似的东西,我相信。
    • @emyller 不。将匹配 foobazbar(foo 不在 foobazbar 之前,所以匹配)
    • @BradKent 我没有在“不匹配”中读到你的“不”,所以我说它会匹配。那么你的案例对我来说就像一个(?!foo)w*bar
    • @BradKent 然后你可以提出一个新问题,详细阐述你想要实现的目标,或者继续使用正则表达式直到你自己找到它。 :)
    【解决方案2】:

    另一种选择是首先匹配可选的单词字符,然后匹配bar,匹配后检查直接在左边的不是foobar

    lookbehind 断言将在首先匹配bar 后运行。

    w*bar(?<!foobar)
    
    • w*匹配0+个单词字符
    • bar字面匹配
    • (?&lt;!foobar) Negative lookbehind,从当前位置断言foobar 不是直接在左边。

    Regex demo

    【讨论】:

      【解决方案3】:

      在某些情况下,可以更容易地选择性地包含前面的部分,然后在第二步中跳过这些匹配项。例如,要查找不以“+”开头的数字:

      if (preg_match_all('/(+?[0-9][0-9s-].*[0-9])/s',$text,$matches)) {
          foreach($matches[1] as $match) {
              if(substr($match,0,1) == '+'){
                  continue;
              }
              // continue processing
          }
      }
      

      后面的负向查找不起作用,因为它仍然会匹配 2+ 个数字,但它不会包括匹配中的第一个数字。例如 +1234 将返回为 234。

      【讨论】:

        猜你喜欢
        • 2012-03-07
        • 2012-01-24
        • 1970-01-01
        • 1970-01-01
        • 2014-01-22
        • 2016-10-19
        • 2020-10-13
        相关资源
        最近更新 更多