【问题标题】:PCRE: backreferences not allowed in lookbehinds?PCRE:回溯中不允许反向引用?
【发布时间】:2015-08-21 02:09:33
【问题描述】:

PCRE 正则表达式 /..(?<=(.)\1)/ 无法编译:“后向断言中不允许子模式引用。”有趣的是,它在前瞻中似乎是可以接受的,比如/(?=(.)\1)../,只是在后视中不行。

是否有技术原因导致后向引用不允许专门用于后向引用?

【问题讨论】:

  • 反向引用通常不能在后视中使用。虽然,一种解决方法是可能的,..(?<=(?=(.)\1))
  • 我想知道为什么,具体来说。甚至/..(?<=(.)(?=\1).)/ 被接受,而/..(?<=(.)\1)/ 不被接受,这似乎变得更奇怪了。
  • 这是因为后视中不允许使用可变长度的子模式。由于反向引用可以有任何长度,因此也不允许在后向引用中使用。对于 pcre,经典的解决方法(如果可能)是使用 \K 功能。
  • 请注意,在分析模式期间,组 1 中的子模式具有恒定长度这一事实完全被忽略。 (很清楚:反向引用 = 可变长度,仅此而已)
  • @WolfgangKluge .NET 是少数可以做到这一点的语言之一。我还没有听说过任何其他能够做到这一点的“通用”语言。

标签: regex pcre regex-lookarounds


【解决方案1】:

使用 Python 的 re 模块,组引用在后向中不受支持,即使它们匹配某个固定长度的字符串。


Lookbehinds 不完全支持 PCRE 规则。具体来说,当正则表达式引擎到达一个lookbehind时,它会尝试确定它的大小,然后跳回去检查匹配。

这种尺寸确定让您做出选择:

  • 允许可变大小,然后每次后退都需要执行才能跳回
  • 不允许变长,那么我们可以直接跳回去

由于第一个解决方案对我们(用户)来说是最好的,它显然是最慢的,也是最难开发的。所以对于 PCRE 正则表达式,他们决定使用第二种解决方案。另一个例子,Java 正则表达式引擎允许半变量后视:您只需要确定最大大小。


我来到了 PCRE 和 Python 的 re 模块。
除了这个错误代码,我在PCRE documentation 中没有找到任何其他内容:

编译错误代码
25:lookbehind assertion 不是固定长度

但在这种情况下,后向断言固定长度。
现在,这是我们可以在re documentation 中找到的内容:

包含的模式必须只匹配一些固定长度的字符串,这意味着 abc 或 a|b 是允许的,但 a* 和 a{3,4} 是不允许的。 不支持组引用,即使它们匹配某个固定长度的字符串。

我们有罪...如果你愿意,你可以试试Python's regex module ,它似乎支持可变长度的lookbehind。

【讨论】:

  • 您有任何参考资料可以证明您的观点吗?也许是PCRE源代码的摘录?听起来会更有说服力。
  • @stribizhev 我在文档深处找到了起源。
猜你喜欢
  • 2011-02-13
  • 2018-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-12
  • 1970-01-01
相关资源
最近更新 更多