如何使用 smartmatch 运算符 ( ~~
) 编写此内容?
use 5.010;
my $string = '12 23 34 45 5464 46';
while ( $string =~ /(\d\d)\s/g ) {
say $1;
}
如何使用 smartmatch 运算符 ( ~~
) 编写此内容?
use 5.010;
my $string = '12 23 34 45 5464 46';
while ( $string =~ /(\d\d)\s/g ) {
say $1;
}
有趣的。perlsyn指出:
任何
~~
正则表达式模式匹配$a =~ /$b/
所以,乍一看,期待似乎是合理的
use strict; use warnings;
use 5.010;
my $string = '12 23 34 45 5464 46';
while ( $string ~~ /(\d\d)\s/g ) {
say $1;
}
打印12
,23
等,但它卡在一个循环中,12
反复匹配。使用:
$ perl -MO=Deparse y.pl
产量
while ($string ~~ qr/(\d\d)\s/g) {
say $1;
}
看着perlop,我们注意到
qr/STRING/msixpo
请注意,“g”没有被列为修饰符(逻辑上,对我来说)。
有趣的是,如果你写:
my $re = qr/(\d\d)\s/g;
perl
吐槽:
Bareword 在 C:\Temp\y.pl 第 5 行找到操作员预期的位置, “qr/(\d\d)\s/g”附近 C:\Temp\y.pl 第 5 行,“qr/(\d\d)\s/g”附近的语法错误
如果在上面的代码中使用了无效的表达式,大概它也应该说些什么
如果我们去看看这两个变体变成了什么,我们就能明白其中的原因。
首先让我们看一下原始版本。
perl -MO=Deparse -e'while("abc" =~ /(.)/g){print "hi\n"}'
while ('abc' =~ /(.)/g) {
print "hi\n";
}
如您所见,操作码没有任何变化。
现在,如果您将其更改为使用智能匹配运算符,您会看到它确实发生了变化。
perl -MO=Deparse -e'while("abc" ~~ /(.)/g){print "hi\n"}'
while ('abc' ~~ qr/(.)/g) {
print "hi\n";
}
它将其更改为qr
,它无法识别该/g
选项。
这可能会给你一个错误,但直到它被解析之后才会被转换。
你应该得到的警告,如果你使用它会得到的警告qr
是:
-e 第 1 行,“qr/(.)/g”附近的语法错误
智能匹配功能从未打算取代=~
操作员。它来自制作given
/when
工作的过程。
大多数时候,
when(EXPR)
被视为 的隐式智能匹配。 ...$_
输出的预期行为是否无休止地首先匹配?因为这就是该代码必须以当前形式执行的操作。问题不在于智能匹配运算符。while 循环是无止境的,因为从未对$string
. /g
全局开关不会改变循环本身。
你想达到什么目的?我假设您要输出两位数的值,每行一个。在这种情况下,您可能需要考虑:
say join("\n", grep { /^\d{2}$/ } split(" ",$string));
老实说,我不确定您是否可以为此使用智能匹配运算符。在我有限的测试中,智能匹配似乎返回一个布尔值而不是匹配列表。但是,您发布的代码(使用=~
)可以在没有它的情况下工作。由于循环
,您发布的内容不起作用。while
循环上的条件语句在while
每次迭代开始之前执行。在这种情况下,您的正则表达式将返回第一个值,$string
因为它在每次迭代时都会被重置。但是Aforeach
会起作用:
my $string = '12 23 34 45 5464 46';
foreach my $number ($string =~ /(\d\d)\s/g) {
print $number."\n";
}