【问题标题】:Decode legacy regular expression: is it a look behind and look ahead?解码遗留正则表达式:是向后看还是向前看?
【发布时间】:2014-06-03 23:27:06
【问题描述】:

我很难用正则表达式阅读旧版 Perl 代码,

$string =~ m/^\(\?\<\!\\S\)/ && $string =~ m/\(\?\!\\S\)$/

我确实了解正则表达式中正面/负面展望的基本概念, 但是,我仍然对这里的真正意图感到非常困惑。

有人能解释一下吗? 谢谢!

【问题讨论】:

  • 第一步:当你想使用正则表达式特殊字符时不要转义它们。
  • 您是否尝试过任何在线正则表达式解释器? (例如,rick.measham.id.au/paste/explain.pl)您会注意到这些正则表达式中没有前瞻或后瞻。
  • 换句话说,只有当您想将其表示为文字字符时,您才需要转义一个特殊字符(对于正则表达式引擎)。
  • @RayToal 该正则表达式解释器基于 Perl 模块 YAPE::Regex::Explain,该模块仅支持 12 年前 Perl 5.6 中当前的 Perl 正则表达式语法子集。它适用于这种情况,但不再是一个好的通用解决方案。
  • 事实上,它无法解释米勒的回答中 \Q\E 做了什么。

标签: regex perl


【解决方案1】:

遗留代码中的正则表达式可以重新编写以更清晰:

$string =~ m{^\Q(?<!\S)\E} && $string =~ m{\Q(?!\S)\E$}

基本上,这匹配以文字 '(?&lt;!\S)' 开头并以文字 '(?!\S)' 结尾的字符串。事实上,我们可以重新设计这个逻辑以完全不使用正则表达式:

substr($string, 0, 7) eq '(?<!\S)' && substr($string, -6) eq '(?!\S)'

那些文字字符串本身看起来像是一个正则表达式否定的向后看和向前看断言,但正则表达式实际上只是试图匹配文字字符串。

【讨论】:

  • \Q..\E,没有看到这个用得太多,但它们确实使regex 模式更容易阅读。
  • @MattGreen 每当有人试图匹配文字字符串时,这是一个相当普遍的事情。 $string =~ m/\Q$literal_string/,但这也是程序员容易忘记的常见错误。
  • 确实,如果你的答案基于给定的模式,\Q \E 似乎是合适的,但我确信 OP 真的想要使用环视。
  • @CasimiretHippolyte 实际上他根本不想要那个。他只是想了解“遗留代码
  • OP 可能不是那个意思,但编写正则表达式的人可能确实如此。然后有人通过一个简单的程序运行它们,通过在每个不是单词字符的字符前面加上一个反斜杠 (``) 来“转义”它们。
【解决方案2】:

如果变量$string以字符序列(?&lt;!\S)开始,并且变量不以字符序列(?!\S)结束,则此表达式返回真。

似乎是代码正在寻找看起来像正则表达式的字符串,以否定的lookbehinds开头,而不是以否定的lookaheads结尾。

所以元。

【讨论】:

  • 我认为你误读了。 \S 实际上也被转义了:\\S。所以它不是在寻找非空格字符。它实际上只是在寻找完整的文字字符串
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-20
  • 2011-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多