正则表达式 – 在回溯和失败后起作用的动词

前端之家收集整理的这篇文章主要介绍了正则表达式 – 在回溯和失败后起作用的动词前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
最近我在 PCRE – (Perl兼容的正则表达式)文档中阅读,并且正式表达了一些有趣的技巧。当我继续阅读和耗尽自己时,我停止了因为使用一些(* …)模式的一些混乱。

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

现在参考(* SKIP)的行为就像(* PRUNE)一样,除了如果模式是无保护的,那么颠簸的提前不是下一个字符,而是在遇到的(* SKIP)主题的位置。

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

所以基本上(* FAIL)的行为就像一个失败的负面断言,是(?!)的同义词

和(* PRUNE)导致匹配失败在主题的当前起始位置,如果有一个后来的匹配失败导致回溯达到它。

How are these different when it comes to a point of failing?

Can anyone provide examples of how these are implemented and used correctly?

在阅读此答案之前,您应该熟悉回溯,原子组和占有量词的机制。您可以在Friedl书中找到有关这些概念和功能的信息,并遵循以下链接www.regular-expressions.infowww.rexegg.com

所有测试都是通过全局搜索(使用preg_match_all()函数进行的)。

(*失败)

baabo caaco daado

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

[0] => aab
[1] => caaco
[2] => aad

(* FAIL)导致与模式中的“坏字符”完全相同的行为。如果用“R”替换,您将获得完全相同的结果:caacR | aa。| caaco | co。为了更通用,你可以通过一个“总是失败的子模式”替换(* FAIL),如:(?!),(?= a(?<!a))... a(第一个来自“baabo”):没有惊喜,第二个选择找到第一个结果。 (aab) c(第一):正则表达式引擎遇到第一个“c”并尝试第一个替代方法,并找到:caac,但子模式被强制失败。那么正则表达式引擎(总是从第一个“c”)尝试失败的第二个替代方案,第三个选项成功。 (caaco) a(第一个来自“daado”):第二个结果是第二个替代。 (aad) (*跳跃)

baabo caaco daado

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

[0] => aab
[1] => co
[2] => aad

该动词定义了一个点,超过此点,当子模式稍后失败时,不允许正则表达式引擎回溯。结果,所有在子模式下发现的所有字符都被一次全部消耗,不能用于模式的另一部分(替代)。

a(第一个来自“baabo”):第二个选择找到第一个结果。 (aab)

c(第一):正则表达式引擎在第一种情况下找到caac,然后失败((FAIL)动词的原因),回溯到第二个“c”,但不允许回溯到先前匹配的字符(“ caa“)之前的(* SKIP)动词。
c(第二):现在,正则表达式引擎总是尝试第一个替代方案,但在这个新的位置,失败,因为有一个“o”而不是“a”之后,它回溯到第二个“c”。请注意,在这种情况下,这些字符不像以前那样被消耗,因为子模式之前已经到达(* SKIP)动词。
第二个选项被测试并失败(不以“c”开头)。第三个选择也失败了,因为下一个字符是“o”而不是“a”。
第四种替代方案成功并获得第二种结果。 (共)

a(第一个来自“daado”):第三个结果是第二个替代。 (aad)

(*修剪)

baabo caaco daado

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

[0] => aab
[1] => aac
[2] => aad

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

a(第一个来自“baabo”):第二个选择找到第一个结果。 (aab)

c(第一):正则表达式引擎在第一种情况下找到caac,然后失败,但是现在从第一个“c”跳回第一个“a”,因为第一个“c”被跳过。
a(第一个来自“caaco”):第一个选择被尝试和失败,第二个成功并给出第二个结果。 (aac)

a(第一个来自“daado”):第三个结果是第二个替代。 (aad)

猜你在找的正则表达式相关文章