动词在回溯和失败后起作用

hwn*_*wnd 24 regex perl pcre

我最近在PCRE- (Perl兼容的正则表达式)文档中阅读并且遇到了一些有规则表达的有趣技巧.当我继续阅读并耗尽自己时,我因为使用​​一些(*...)模式而产生了一些混乱而停止了.

我的问题和困惑与(*PRUNE)(*FAIL)

现在对于参考(*SKIP)行为(*PRUNE),除了如果模式是未锚定的,则不等于前一个字符,而是到达主题中遇到的位置(*SKIP).

文档说明如果模式的其余部分不匹配,则(*PRUNE)导致匹配在主题中的当前起始位置失败.它表示否定断言的(*FAIL)同义词(?!).在模式中的给定位置强制匹配失败.

所以基本上(*FAIL)表现得像一个失败的否定断言,并且是一个同义词(?!)

并且如果存在导致回溯到达的后续匹配故障,则导致匹配在主题(*PRUNE)中的当前起始位置处失败.

当谈到失败的时候,这些有何不同?

任何人都可以提供如何正确实施和使用这些示例吗?

Cas*_*yte 34

在阅读这个答案之前,你应该熟悉回溯,原子组和占有量词的机制.您可以在Friedl一书中找到有关这些概念和特征的信息,并点击以下链接:www.regular-expressions.info,www.rexegg.com

所有测试都是通过全局搜索(使用该preg_match_all()功能)完成的.

(*失败)

baabo caaco daado

caac(*FAIL)|aa.|caaco|co

[0] => aab
[1] => caaco
[2] => aad
Run Code Online (Sandbox Code Playgroud)

(*FAIL)导致与模式中的"坏字符"完全相同的行为.如果用"R"替换它,你会得到完全相同的结果:caacR|aa.|caaco|co.更一般地说,你确实可以用(*FAIL)"总是失败的子模式" 代替:(?!),(?=a(?<!a))......

a (first from "baabo"):毫不奇怪,第一个结果是第二个替代品.(aab)

c (first):正则表达式引擎遇到第一个"c"并尝试第一个替代方法并找到:caac,但子模式被强制失败.然后正则表达式引擎(始终从第一个"c")尝试第二个替代失败,第三个替代成功.(caaco)

a (first from "daado"):第三个结果是第二个替代方案.(aad)

(*跳跃)

baabo caaco daado

caa(*SKIP)c(*FAIL)|aa.|caaco|co

[0] => aab
[1] => co
[2] => aad
Run Code Online (Sandbox Code Playgroud)

此动词定义了一个点,超过该点,当子模式稍后失败时,不允许正则表达式引擎回溯.结果,之前在子模式中找到的所有字符都是一劳永逸地消耗的,并且不能用于模式的另一部分(替代).

a (first from "baabo"):第一个结果是由第二个替代品找到的.(aab)

c (first):正则表达式引擎caac在第一种情况下发现,然后失败((*FAIL)动词的原因),回溯到第二个"c"但不允许回溯到(*SKIP)动词之前先前匹配的字符("caa").
c (second):现在,正则表达式引擎总是尝试第一种选择但是在这个新位置并且由于之后有"o"而不是"a"而失败,然后它回溯到第二个"c".请注意,在这种情况下,这些字符不会像以前那样被消耗,因为子模式在到达(*SKIP)动词之前已经失败.第二种方法是测试并失败(不以"c"开头).第三种选择也失败了,因为下一个字符是"o"而不是"a".第四种选择成功并给出第二种结果.(co)

a (first from "daado"):第三个结果是第二个替代方案.(aad)

(*修剪)

baabo caaco daado

caa(*PRUNE)c(*FAIL)|aa.|caaco|co

[0] => aab
[1] => aac
[2] => aad
Run Code Online (Sandbox Code Playgroud)

此动词不同于(*SKIP)因为它不禁止使用所有先前匹配的字符,但是如果子模式稍后将失败,则子模式会跳过第一个匹配的字符(或禁止以子模式开头).

a (first from "baabo"):第一个结果是由第二个替代品找到的.(aab)

c (first):正则表达式引擎caac在第一种情况下发现,然后失败,但现在从"caaco"回溯到第一个"a",因为跳过了第一个"c".
a (first from "caaco"):第一个替代尝试失败,第二个成功并给出第二个结果.(aac)

a (first from "daado"):第三个结果是第二个替代方案.(aad)

  • 太伤心了,这个伟大的答案只看了370次! (3认同)
  • 很酷,这是我的第一个赏金!谢谢@HamZa. (2认同)