为什么单个数字无法匹配数组中的 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 的回答的评论。)
> 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 的回答的评论。)