在 Raku 上,我们如何从相应的正则表达式捕获中单独填写多个变量

How on Raku do we fill out multi variables individually from corresponding regex captures

最简单的 Raku 是如何从正则表达式捕获的结果中以相应顺序填写这么多单个变量的
(就像 Perl my ($a, $b $c, $d, $e)= 'hello' =~ m{ ^(h) (e) (l) (l) (o) }x

) ?

试试这样:

> my ($a, $b, $c, $arr);
[<$a $b $c>]= 'hello world' ~~ m{ (h)(e)(l)lo };
say "\n=$a\n=$b\n=$c"

Use of uninitialized value element of type Any in string context.
    Methods .^name, .raku, .gist, or .say can be used to stringify it to something meaningful.
      in block <unit> at <unknown file> line 1

...

失败。
请显示正确和最接近 Perl 的方法。

#my ($a, $b, $c, $d, $e) = 'hello' =~ m{ ^(h) (e) (l) (l) (o) }x;      # Perl
 my ($a, $b, $c, $d, $e) = 'hello' ~~ m{ ^(h) (e) (l) (l) (o) } .list; # Raku

解释差异:

  • { ... }x 在 Perl 中,正则表达式中的白色 space 是模式的一部分,除非您附加 x adverb/option。在 Raku 不是这样。

  • .list。在 Perl 中,匹配操作一般 return 要么是一个字符串,要么是一串字符串。在 Raku 中也是一样的,除了:

    • 值 returned 是 Match objects,不是字符串。 (如果将它们视为字符串,它们会方便地自动强制转换为字符串,但有时差异很重要,并且极大地扩展了 Raku 可以使用 returned 匹配 possible/easy。)

    • 许多操作 return 单个 Match object 当 Perl 用户期望一个列表时。你的情况就是一个例子。但是 究竟是 一个 object?你是一个人。但你还不止于此。

    • Raku 中的某些 object 是“child”object 的“parent”。 (Match object 就是一个很好的例子。)Children 通常可以通过对 parent 应用适当的操作来访问。你的情况就是一个例子。 .list 通常会作为一种惯用的方式来获得 numbered children,.hash for named child仁。如果给定的 class/object 支持它,那么许多方法中的另一种方法是下标:

      say ('foo' ~~ m{ (.) (.) })[*];                          # (「f」 「o」)
      say ('foo' ~~ m{ (.) (.) $<I'm-named>=(.) })<I'm-named>; # 「o」
      

为什么额外的复杂性?对于 Match objects 来说,让通用解析的巨大额外功能和实用性自动且轻松地可用是一种权衡。有关此问题的更多讨论,请参阅

按照 Raiph 的回答,你永远不会做错。但我将尝试解释一下为什么这样做有效,并提出替代方案。 Match is a Capture, a beast that's essentially a list and an associative array at the same time. What you want is to have the result as a list, same as it happens in Perl. How do you extract the "list" part (or coerce it to a list)? Easy: use explicit coercion (as Raiph suggests) or try and put it in a list context. What creates a list context? Flattening 做:

my ($a, $b, $c, $d, $e) = |('hello' ~~ m{ ^(h) (e) (l) (l) (o) });

列表绑定也是如此:

my ($a, $b, $c, $d, $e) := 'hello' ~~ m{ ^(h) (e) (l) (l) (o) };

问题是每个变量仍然包含一个匹配项;您可能想要的是与 Perl 中相同的东西,一个字符串列表。我们可以用这个组合得到它:

my @array is Array[Str(Match)] = | ('hello' ~~ m{ ^(h) (e) (l) (l) (o) });

我们在右侧获取列表上下文,并通过使用 coercing elements 显式声明数组,结果得到 [h e l l o]