我一直试图找出如何在Perl 6中执行递归正则表达式。对于一个玩具示例,一个平衡的括号匹配器将与((())())
中的(((((())())
匹配。
我认为这可以做到:
my regex paren {
'(' ~ ')' <paren>*
}
或更简单
my regex paren {
'(' <paren>* ')'
}
但是失败
No such method 'paren' for invocant of type 'Match'
in regex paren at ...
答案 0 :(得分:15)
您需要明确说明您正在调用my
范围的正则表达式:
my regex paren {
'(' ~ ')' <&paren>*
}
请注意已添加的&
。这样:
say "(()())" ~~ /^<&paren>$/ # 「(()())」
say "(()()" ~~ /^<&paren>$/ # Nil
虽然确实可以有时通过显式编写&
而逃脱,但确实可以在使用时使用它:
say "(()())" ~~ /^<paren>$/ # 「(()())」
say "(()()" ~~ /^<paren>$/ # Nil
这仅起作用,因为编译器发现在词法范围内定义了一个名称为paren
的正则表达式,因此将<paren>
语法编译为该正则表达式。对于递归情况,直到解析正则表达式后才安装该声明,因此需要明确声明。
答案 1 :(得分:1)
您可以在元语法中使用~~
来对当前模式或其一部分进行递归回调。例如,您可以将平衡括号与简单的正则表达式匹配:
say "(()())" ~~ /'(' <~~>* ')'/; # 「(()())」
say "(()()" ~~ /'(' <~~>* ')'/; # 「()」
不幸的是,尚未通过捕获的子规则(如~~0
)进行匹配。