正则表达式递归:第 N 个子模式
Regex Recursion: Nth Subpatterns
我正在尝试学习正则表达式中的递归,并对 PCRE 风格中的概念有一个基本的了解。我想打断一个字符串:
Geese (Flock) Dogs (Pack)
进入:
Full Match: Geese (Flock) Dogs (Pack)
Group 1: Geese (Flock)
Group 2: Geese
Group 3: (Flock)
Group 4: Dogs (Pack)
Group 5: Dogs
Group 6: (Pack)
我不知道这两个正则表达式都不会这样做,但我更好奇 first pattern works, but the second 不这样做的原因。
Pattern 1: ((.*?)(\(\w{1,}\)))((.*?)(\g<3>))*
Pattern 2: ((.*?)(\(\w{1,}\)))((\g<2>)(\g<3>))*
此外,例如,如果您正在处理一个长字符串,并且一个模式会自我重复,是否可以不断扩展完整匹配,并逐步增加组,而无需编写与正则表达式分开的循环语句。
Full Match: Geese (Flock) Dogs (Pack) Elephants (Herd)
Group 1: Geese (Flock)
Group 2: Geese
Group 3: (Flock)
Group 4: Dogs (Pack)
Group 5: Dogs
Group 6: (Pack)
Group 7: Elephants (Herd)
Group 8: Elephants
Group 9: (Herd)
这是 closest 我得到的是这个模式,但中间组:狗(Pack)变成组 0。
((.*?)(\(\w{1,}\)))((.*?)(\g<3>))*
请注意 PCRE 中的递归级别是原子的。一旦这些模式找到匹配项,它们将永远不会重试。
见Recursion and Subroutine Calls May or May Not Be Atomic:
Perl and Ruby backtrack into recursion if the remainder of the regex after the recursion fails. They try all permutations of the recursion as needed to allow the remainder of the regex to match. PCRE treats recursion as atomic. PCRE backtracks normally during the recursion, but once the recursion has matched, it does not try any further permutations of the recursion, even when the remainder of the regex fails to match. The result is that Perl and Ruby may find regex matches that PCRE cannot find, or that Perl and Ruby may find different regex matches.
你的第二个模式,在第一个递归级别,看起来像
((.*?)(\(\w{1,}\)))(((?>.*?))((?>\(\w{1,}\))))*
^^^^^^^ ^^^^^^^^^^^^^^
参见 demo。也就是说,\g<2>
是 (?>.*?)
,而不是 .*?
。这意味着,在 ((.*?)(\(\w{1,}\)))
模式匹配 Geese (Flock)
之后,正则表达式引擎尝试与 (?>.*?)
匹配,看到它是一个不需要消耗任何字符的惰性模式,跳过它(并且永远不会回到这种模式),并尝试与 (?>\(\w{1,}\))
匹配。由于 )
之后没有 (
,正则表达式 returns 它消耗了什么。
至于第二个问题,这是一个普遍的问题。使用 PCRE 正则表达式不可能获得任意数量的捕获,因为在重复捕获的情况下,只有最后捕获的值存储在组缓冲区中。结果数组中的子匹配项不能多于正则表达式模式中捕获组的数量。有关详细信息,请参阅 Repeating a Capturing Group vs. Capturing a Repeated Group。
我正在尝试学习正则表达式中的递归,并对 PCRE 风格中的概念有一个基本的了解。我想打断一个字符串:
Geese (Flock) Dogs (Pack)
进入:
Full Match: Geese (Flock) Dogs (Pack)
Group 1: Geese (Flock)
Group 2: Geese
Group 3: (Flock)
Group 4: Dogs (Pack)
Group 5: Dogs
Group 6: (Pack)
我不知道这两个正则表达式都不会这样做,但我更好奇 first pattern works, but the second 不这样做的原因。
Pattern 1: ((.*?)(\(\w{1,}\)))((.*?)(\g<3>))*
Pattern 2: ((.*?)(\(\w{1,}\)))((\g<2>)(\g<3>))*
此外,例如,如果您正在处理一个长字符串,并且一个模式会自我重复,是否可以不断扩展完整匹配,并逐步增加组,而无需编写与正则表达式分开的循环语句。
Full Match: Geese (Flock) Dogs (Pack) Elephants (Herd)
Group 1: Geese (Flock)
Group 2: Geese
Group 3: (Flock)
Group 4: Dogs (Pack)
Group 5: Dogs
Group 6: (Pack)
Group 7: Elephants (Herd)
Group 8: Elephants
Group 9: (Herd)
这是 closest 我得到的是这个模式,但中间组:狗(Pack)变成组 0。
((.*?)(\(\w{1,}\)))((.*?)(\g<3>))*
请注意 PCRE 中的递归级别是原子的。一旦这些模式找到匹配项,它们将永远不会重试。
见Recursion and Subroutine Calls May or May Not Be Atomic:
Perl and Ruby backtrack into recursion if the remainder of the regex after the recursion fails. They try all permutations of the recursion as needed to allow the remainder of the regex to match. PCRE treats recursion as atomic. PCRE backtracks normally during the recursion, but once the recursion has matched, it does not try any further permutations of the recursion, even when the remainder of the regex fails to match. The result is that Perl and Ruby may find regex matches that PCRE cannot find, or that Perl and Ruby may find different regex matches.
你的第二个模式,在第一个递归级别,看起来像
((.*?)(\(\w{1,}\)))(((?>.*?))((?>\(\w{1,}\))))*
^^^^^^^ ^^^^^^^^^^^^^^
参见 demo。也就是说,\g<2>
是 (?>.*?)
,而不是 .*?
。这意味着,在 ((.*?)(\(\w{1,}\)))
模式匹配 Geese (Flock)
之后,正则表达式引擎尝试与 (?>.*?)
匹配,看到它是一个不需要消耗任何字符的惰性模式,跳过它(并且永远不会回到这种模式),并尝试与 (?>\(\w{1,}\))
匹配。由于 )
之后没有 (
,正则表达式 returns 它消耗了什么。
至于第二个问题,这是一个普遍的问题。使用 PCRE 正则表达式不可能获得任意数量的捕获,因为在重复捕获的情况下,只有最后捕获的值存储在组缓冲区中。结果数组中的子匹配项不能多于正则表达式模式中捕获组的数量。有关详细信息,请参阅 Repeating a Capturing Group vs. Capturing a Repeated Group。