如何在 Raku 中插入包含捕获组括号的字符串作为正则表达式?
how to interpolate string containing capture-group parentheses as regex in Raku?
我想匹配以编程方式构造的正则表达式,其中包含许多 (.*)
捕获组。我把这个正则表达式作为一个字符串,比如
my $rx = "(.*)a(.*)b(.*)"
我想将该字符串插入为正则表达式并匹配它。 docs 告诉我 <$rx>
应该可以解决问题(即将该字符串插入为正则表达式),但事实并非如此。比较匹配的输出(在 perl6
REPL 中):
> 'xaybz' ~~ rx/<$rx>/
「xaybz」
vs expected/desired 输出,区分捕获组:
> 'xaybz' ~~ rx/(.*)a(.*)b(.*)/
「xaybz」
0 => 「x」
1 => 「y」
2 => 「z」
评论
我可以做到这一点的一个没有吸引力的方法是 EVAL 我的正则表达式匹配(也在 REPL 中):
> use MONKEY; EVAL "'xaybz' ~~ rx/$rx/";
「xaybz」
0 => 「x」
1 => 「y」
2 => 「z」
所以虽然这确实给了我 a 解决方案,但我确信我缺少一个字符串插值技巧,它可以避免依赖 EVAL
..
进行匹配的结果在超出正则表达式时被匹配。这将起作用:
my $rx = '(.*)a(.*)b(.*)';
'xaybz' ~~ rx/$<result>=<$rx>/;
say $<result>;
# OUTPUT: «「xaybz」 0 => 「x」 1 => 「y」 2 => 「z」»
因为,通过分配给匹配变量,您正在访问原始匹配,然后您可以打印它。问题是 <$rx> 实际上是一个匹配项,而不是一个字符串。所以你正在做的是一个匹配匹配项的正则表达式。可能 Match 被字符串化,然后匹配。这是我最接近解释结果的方法
问题是 <…>
中的东西一般不会捕获。
'xaybz' ~~ / <:Ll> <:Ll> <:Ll> /
# 「xay」
如果 <
之后的第一件事是字母,他们会捕获。
my regex foo { (.*)a(.*)b(.*) }
'xaybz' ~~ / <foo> /;
# 「xaybza」
# foo => 「xaybza」
# 0 => 「x」
# 1 => 「y」
# 2 => 「za」
如果您使用 <a=…>
,这也适用
'xaybz' ~~ / <rx=$rx> /;
# 「xaybza」
# rx => 「xaybza」
# 0 => 「x」
# 1 => 「y」
# 2 => 「za」
当然你也可以在外面赋值
'xaybz' ~~ / $<rx> = <$rx> /;
# 「xaybza」
# rx => 「xaybza」
# 0 => 「x」
# 1 => 「y」
# 2 => 「za」
'xaybz' ~~ / [=13=] = <$rx> /;
# 「xaybza」
# 0 => 「xaybza」
# 0 => 「x」
# 1 => 「y」
# 2 => 「za」
请注意 <…>
是 sub-match,因此 $rx
中的 [=18=]
、</code>、<code>
永远不会打开top-level.
您可以执行以下操作以将内部正则表达式结果公开给外部变量:
my $rx = "(.*)a(.*)b(.*)";
my $result;
'xaybz' ~~ / $<result>=<$rx> {$result = $<result>}/;
say $result;
# OUTPUT:
# 「xaybz」
# 0 => 「x」
# 1 => 「y」
# 2 => 「z」
我想匹配以编程方式构造的正则表达式,其中包含许多 (.*)
捕获组。我把这个正则表达式作为一个字符串,比如
my $rx = "(.*)a(.*)b(.*)"
我想将该字符串插入为正则表达式并匹配它。 docs 告诉我 <$rx>
应该可以解决问题(即将该字符串插入为正则表达式),但事实并非如此。比较匹配的输出(在 perl6
REPL 中):
> 'xaybz' ~~ rx/<$rx>/
「xaybz」
vs expected/desired 输出,区分捕获组:
> 'xaybz' ~~ rx/(.*)a(.*)b(.*)/
「xaybz」
0 => 「x」
1 => 「y」
2 => 「z」
评论
我可以做到这一点的一个没有吸引力的方法是 EVAL 我的正则表达式匹配(也在 REPL 中):
> use MONKEY; EVAL "'xaybz' ~~ rx/$rx/";
「xaybz」
0 => 「x」
1 => 「y」
2 => 「z」
所以虽然这确实给了我 a 解决方案,但我确信我缺少一个字符串插值技巧,它可以避免依赖 EVAL
..
进行匹配的结果在超出正则表达式时被匹配。这将起作用:
my $rx = '(.*)a(.*)b(.*)';
'xaybz' ~~ rx/$<result>=<$rx>/;
say $<result>;
# OUTPUT: «「xaybz」 0 => 「x」 1 => 「y」 2 => 「z」»
因为,通过分配给匹配变量,您正在访问原始匹配,然后您可以打印它。问题是 <$rx> 实际上是一个匹配项,而不是一个字符串。所以你正在做的是一个匹配匹配项的正则表达式。可能 Match 被字符串化,然后匹配。这是我最接近解释结果的方法
问题是 <…>
中的东西一般不会捕获。
'xaybz' ~~ / <:Ll> <:Ll> <:Ll> /
# 「xay」
如果 <
之后的第一件事是字母,他们会捕获。
my regex foo { (.*)a(.*)b(.*) }
'xaybz' ~~ / <foo> /;
# 「xaybza」
# foo => 「xaybza」
# 0 => 「x」
# 1 => 「y」
# 2 => 「za」
如果您使用 <a=…>
'xaybz' ~~ / <rx=$rx> /;
# 「xaybza」
# rx => 「xaybza」
# 0 => 「x」
# 1 => 「y」
# 2 => 「za」
当然你也可以在外面赋值
'xaybz' ~~ / $<rx> = <$rx> /;
# 「xaybza」
# rx => 「xaybza」
# 0 => 「x」
# 1 => 「y」
# 2 => 「za」
'xaybz' ~~ / [=13=] = <$rx> /;
# 「xaybza」
# 0 => 「xaybza」
# 0 => 「x」
# 1 => 「y」
# 2 => 「za」
请注意 <…>
是 sub-match,因此 $rx
中的 [=18=]
、</code>、<code>
永远不会打开top-level.
您可以执行以下操作以将内部正则表达式结果公开给外部变量:
my $rx = "(.*)a(.*)b(.*)";
my $result;
'xaybz' ~~ / $<result>=<$rx> {$result = $<result>}/;
say $result;
# OUTPUT:
# 「xaybz」
# 0 => 「x」
# 1 => 「y」
# 2 => 「z」