:ex 和 :ov 副词与 Perl 6 命名捕获

:ex and :ov adverbs with Perl 6 named captures

我不太明白,为什么这里的结果不同。 :ov 是否只适用于 <left>,所以找到最长的匹配后它不会做任何其他事情吗?

my regex left {
    a  | ab
}
my regex right {
    bc | c
}

"abc" ~~ m:ex/<left><right> 
   {put $<left>, '|', $<right>}/; # 'ab|c' and 'a|bc'
say '---';

"abc" ~~ m:ov/<left><right> 
   {put $<left>, '|', $<right>}/; # only 'ab|c'

:ex 将找到所有可能的重叠匹配组合。

:ov:ex 类似,只是它限制了搜索算法,将其限制为仅针对给定的起始位置查找单个匹配项,从而使其针对给定的长度生成单个匹配项. :ex允许从字符串的最开头开始寻找新的唯一匹配,所以它可能会找到多个长度为3的匹配; :ov 只会找到一个长度为 3 的匹配项。

文档:
https://docs.perl6.org/language/regexes

Exhaustive:

To find all possible matches of a regex – including overlapping ones – and several ones that start at the same position, use the :exhaustive (short :ex) adverb

Overlapping:

To get several matches, including overlapping matches, but only one (the longest) from each starting position, specify the :overlap (short :ov) adverb:

副词的类型

了解有两种不同类型的正则表达式副词很重要:

  1. 微调正则表达式代码编译方式的那些(例如 :sigspace/:s:ignorecase/:i、...)。这些也可以写在正则表达式中,并且仅适用于正则表达式中的其余词法范围。
  2. 那些控制如何找到和返回正则表达式匹配项(例如 :exhaustive/:ex:overlap/:ov:global/:g).这些适用于整个给定的正则表达式匹配操作,并且必须写在正则表达式之外,作为 m// 运算符或 .match 方法的副词。

匹配副词

第二类相关副词的作用如下:

  • m:ex/.../ 在每个可能的起始位置找到每个可能的匹配项。
  • m:ov/.../ 在每个可能的起始位置找到 第一个 可能的匹配项。
  • m:g/.../ 在上一个匹配结束后的每个可能的起始位置找到 first 可能的匹配(即非重叠)。
  • m/.../first 可能的起始位置找到 first 可能的匹配项。

(在每种情况下,正则表达式引擎一旦在任何给定位置找到了要查找的内容,就会继续运行,这就是为什么即使将 print 语句放在正则表达式中也看不到额外的输出。 )

你的例子

对于您的情况,只有两种可能的匹配:ab|ca|bc
两者都从输入字符串中的相同位置开始,即位置 0。
所以只有 m:ex/.../ 会同时找到它们 - 所有其他变体只会找到其中一个然后继续前进。