为什么单个数字无法匹配数组中的 Range 对象?

Why does a single number fail to match a Range object in an array?

> my @numbers = 1, 3, 5;
> 1 ~~ /@numbers/; # 
「1」

等同于:

> 1 ~~ /1 | 3 | 5/
「1」

但是当元素是Range对象时,匹配失败:

> my @ranges = 1..3.item, 4..6.item;
[1..3 4..6]

> 1 ~~ /@ranges/
Nil
> 1 ~~ /|@ranges/
Nil
> 1 ~~ /||@ranges/

当正则表达式引擎看到 /@numbers/ 时,它会将其视为数组元素的交替,因此您的前两个示例是等效的。

我相信 Range 没有这样的自动化。

编辑:没关系,我一开始完全看错了这个问题。

> my @ranges = 1..3, 4..6;
[1..3 4..6]
> 1 ~~ @ranges[0];
True
> 2 ~~ @ranges[1];
False
> 4 ~~ @ranges[1];
True
> @ranges.first( 5 ~~ * )
4..6

看到了吗? @ranges 是一个范围数组(您对 item 的调用在这里没有任何作用)。 理论上如果智能匹配运算符更聪明,这个成立。

> 1..3 ~~ @ranges;
False

扁平化也无济于事,因为范围的扁平列表仍然是范围列表。

可以将范围本身展平,但这只是将它们变成数组

> my @ranges2 = |(1..3), |(4..6)
[1 2 3 4 5 6]

Why does single number fails to match Range object in array?

根据 the doc:

The interpolation rules for individual elements [of an array] are the same as for scalars

根据同一文档部分,标量(不是正则表达式)的规则是:

interpolate the stringified value

范围对象如 1..3 字符串化为 1 2 3:

my $range = 1..3;
put $range;                   # 1 2 3
put so '1'     ~~ / $range /; # False
put so '1 2 3' ~~ / $range /; # True

因此,正如 Holli 所建议的那样,也许相反:

my @ranges = flat 1..3, 4..6;
say @ranges;        # [1 2 3 4 5 6]
say 1 ~~ /@ranges/; # 「1」

或者你有什么理由不想这样? (另请参阅 Scimon 对 Holli 的回答的评论。)