Jul*_*lio 10 regex rakudo regex-group regex-alternation raku
使用 perl(以及几乎所有正则表达式),每个组都按顺序编号。
例如,这段代码:
'bar' =~ m/(foo)|(bar)/;
print $1 // 'x'; # (1-based index)
print $2 // 'x'; # (1-based index)
Run Code Online (Sandbox Code Playgroud)
印刷 xbar
但是,对于 Raku,它的行为就像有一个分支重置组包裹了整个正则表达式:
'bar' ~~ m/(foo)|(bar)/;
print $0 // 'x'; # (0-based index)
print $1 // 'x'; # (0-based index)
Run Code Online (Sandbox Code Playgroud)
印刷 barx
我对这种行为没意见:)。然而,有时知道哪个组在交替下被捕获是有用的。
怎么知道有raku的组?
use*_*601 10
有几种方法可以做到,具有不同程度的效用。
一种方法是明确告诉 Raku 你想要的数字是什么:
'bar' ~~ m/$1=(foo)|$2=(bar)/;
Run Code Online (Sandbox Code Playgroud)
如果您扩展正则表达式,计数将继续以 3 美元计算。
一个不太推荐的方法是偷偷加入一组额外的括号:
'bar' ~~ m/(foo)|()(bar)/;
Run Code Online (Sandbox Code Playgroud)
foo将匹配 $0 中的第一个并且 $1 将是未定义的,并且bar将匹配 $1 并且 $0 为空(但不是未定义)。TIMTOWTDI 但这不是一个好方法 ;-)
另一种方法是使用标志:
my $flag;
'bar' ~~ m/(foo {$flag = 'first'} ) | (bar {$flag = 'second'} )/;
Run Code Online (Sandbox Code Playgroud)
标志将根据比赛设置。这实际上是一种并不可怕的做事方式,特别是如果您的标志是二进制的并且您将有一些逻辑可以运行它。
另一种类似的方法是利用通常在动作类中使用的.make/ .made,但仍然可以内联使用:
'bar' ~~ m/(foo {make 'first'} ) | (bar {make 'second'} )/;
say $0.made; # 'second'
Run Code Online (Sandbox Code Playgroud)
如果您有很多想要与之关联的元数据(但仅仅知道选择了哪个可能有点过分),那么这个就很好了。