【问题标题】:regexp to match string1 unless preceded by string2正则表达式匹配 string1,除非前面有 string2
【发布时间】:2010-11-15 20:36:25
【问题描述】:

使用 Ruby,我如何使用单个正则表达式匹配“xy y ay xy +y”中所有出现的“y”,但前面没有 x (y, ay, +y)?
/[^x]y/ 也匹配前面的字符,所以我需要一个替代...

【问题讨论】:

标签: ruby regex string regex-negation


【解决方案1】:

您需要一个零宽度的否定后视断言。试试/(?<!x)y/,它准确地说明了您要查找的内容,即查找所有前面没有“x”的“y”,但不包括前面的字符,即零宽度部分。

编辑添加:显然这仅在 Ruby 1.9 及更高版本中受支持。

【讨论】:

    【解决方案2】:

    在 Ruby 1.9 之前不支持负向后查看,但您可以使用扫描执行类似的操作:

    "xy y ay xy +y".scan(/([^x])(y)/) # => [[" ", "y"], ["a", "y"], ["+", "y"]]
    "xy y ay xy +y".scan(/([^x])(y)/).map {|match| match[1]}  # => ["y", "y", "y"]
    

    当然,如果您想避免y 之前的多个字符,这要困难得多。然后你必须做类似的事情:

    "abby y crabby bally +y".scan(/(.*?)(y)/).reject {|str| str[0] =~ /ab/}  # => [[" ", "y"], [" ball", "y"], [" +", "y"]]
    "abby y crabby bally +y".scan(/(.*?)(y)/).reject {|str| str[0] =~ /ab/}.map {|match| match[1]}  # => ["y", "y" "y"]
    

    【讨论】:

      【解决方案3】:

      不幸的是,Ruby 不支持负向回溯,因此如果您需要查找多个字符,您将遇到麻烦。对于一个角色,您可以通过捕获匹配来解决这个问题:

      /[^x](y)/
      

      【讨论】:

      • 啊,我不是 Ruby 专家 - jbourque 说消极的后视是在较新的 Ruby 中。这是你真正的答案。
      • [^x] 必须匹配一个字符。如果 y 出现在行首,我们应该匹配它: /(?:\A|^|[^x])y/
      【解决方案4】:

      在 PCRE 中,您使用否定的后视:

      (:<!x)y
      

      不确定 Ruby 是否支持此功能,但您可以随时查找。

      【讨论】:

        【解决方案5】:

        可以用消极的眼神来完成,(?&lt;!x)y

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-08-28
          • 2013-05-11
          • 1970-01-01
          • 2019-01-13
          • 2017-05-09
          • 1970-01-01
          • 2014-01-22
          • 1970-01-01
          相关资源
          最近更新 更多