【问题标题】:php regex: Alternative to backreference in negative lookbehindphp 正则表达式:替代反向引用中的负面回溯
【发布时间】:2018-11-15 22:00:52
【问题描述】:

我想查找捕获的组没有出现在字符串后面的实例:

aaaBbb  = CccBbb  <- format is valid, skip
aaaDddd = CccDddd <- format is valid, skip
aaaEeee = CccFfff <- format is not valid, match this one only

所以这匹配了我不想匹配的行 (https://regex101.com/r/lon87L/1)

/^ +\w+([A-Z][a-z+]) += +\w+\1$/mg

我在https://www.regular-expressions.info/refadv.html 上读到过,php 不支持负后向内的反向引用,但正则表达式的其他实现可以。所以这样的事情会匹配我想要匹配的无效行,但它在 php 中不起作用:

/^ +\w+([A-Z][a-z+]) += +\w+(?<!\1)$/mg

除了匹配所有三行并在 php foreach 中循环匹配之外,还有其他方法可以吗?

【问题讨论】:

  • 负面的lookbehinds需要一个固定的编译时间长度。反向引用是具有可变长度的运行时项。一种选择是(?&gt;\1(*SKIP)(*FAIL)|\w)+ 并匹配反向引用。这可能也更快。
  • 你可以在这里看到它regex101.com/r/6gfSBi/1顺便说一句,只有Dot-Net引擎支持可变宽度的lookbehinds(包括反向引用)。
  • 如果必须在 EOS 上,只需在 backref regex101.com/r/QuXJLY/1 后添加 $

标签: php regex negative-lookbehind


【解决方案1】:

尝试使用否定的前瞻而不是否定的后瞻。它同样工作得很好,而且它在 PHP 中也能工作。

^ +\w+([A-Z][a-z]+) += +(?!\w+\1).*$

regex101 demo

PHP demo

【讨论】:

    【解决方案2】:

    一种选择是,在= 之后的每个重复\w 之前,对\1$ 使用负前瞻:

    ^ +\w+([A-Z][a-z]+) += +(?:(?!\1$)\w)+$
                            ^^^^^^^^^^^^^^
    

    https://regex101.com/r/lon87L/2

    但只有当反向引用出现在字符串的末尾时才会排除匹配。如果您想确保之前匹配的短语不会出现在最后的\ws 中任何地方,只需从重复组中删除$

    ^ +\w+([A-Z][a-z]+) += +(?:(?!\1)\w)+$
                                    ^
    

    https://regex101.com/r/lon87L/3

    【讨论】:

      猜你喜欢
      • 2017-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-06
      • 1970-01-01
      • 2020-06-08
      • 1970-01-01
      相关资源
      最近更新 更多