正则表达式引擎如何使用递归子模式解析正则表达式?

ale*_*y2k 5 php regex recursion pcre palindrome

这个正则表达式匹配回文: ^((.)(?1)\2|.?)$

无法绕过它的工作原理.递归何时结束,以及当regex从递归子模式中断并转到"|.?"部分时?

谢谢.

编辑:抱歉,我没有解释\2(?1)

(?1) - 指第一个子模式(对自己)

\2 - 返回引用第二个子模式的匹配,即 (.)

以上用PHP编写的示例.匹配"abba"(没有中间回文字符)和"abcba" - 具有中间的,未反映的字符

nha*_*tdh 4

^((.)(?1)\2|.?)$

^分别$断言字符串的开头和结尾。我们看看中间的内容,比较有趣:

((.)(?1)\2|.?)
1------------1 // Capturing group 1
 2-2           // Capturing group 2
Run Code Online (Sandbox Code Playgroud)

看第一部分(.)(?1)\2,我们可以看到它会尝试匹配任何字符,以及末尾的相同字符(反向引用\2,指的是 匹配的字符(.))。中间,它将递归匹配整个捕获组1。注意,有一个隐式断言(由(.)在开头匹配一个字符和\2在结尾匹配相同字符引起)要求字符串至少为2个字符。第一部分的目的是递归地砍掉字符串的相同末端。

看第二部分.?,我们可以看到它将匹配 1 个或 0 个字符。仅当字符串最初长度为 0 或 1,或者递归匹配的剩余部分为 0 或 1 个字符时,才会匹配。第二部分的目的是匹配空字符串或字符串从两端截断后的单个孤独字符。

递归匹配的工作原理:

  • 整个字符串必须是回文才能传递,由^和断言$。我们不能从任何随机位置开始匹配。
  • 如果字符串 <= 1 个字符,则通过。
  • 如果字符串> 2个字符,则仅由第一部分决定是否接受。如果匹配,它将被2端砍断。
  • 剩下的如果匹配,只能被两端切掉,或者如果其长度 <= 1,则通过。

  • 每次由于第一部分而递归时,它都会处理删除两个结尾字符的字符串。最终它缩小到 0 或 1 个字符,然后第二部分匹配并且递归停止。 (2认同)