如何使用smartmatch运算符(~~
)编写此代码?
use 5.010;
my $string = '12 23 34 45 5464 46';
while ( $string =~ /(\d\d)\s/g ) {
say $1;
}
答案 0 :(得分:4)
有趣。 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
barfs:
Bareword found where operator expected at C:\Temp\y.pl line 5, near "qr/(\d\d)\s/g" syntax error at C:\Temp\y.pl line 5, near "qr/(\d\d)\s/g"
并且如果在上面的代码中使用了无效的表达式,也可能会说些什么
答案 1 :(得分:1)
如果我们去看看这两个变体被转化为什么,我们可以看到它的原因。
首先让我们看看原始版本。
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
,则会得到警告:
syntax error at -e line 1, near "qr/(.)/g"
智能匹配功能从未打算取代=~
运算符。它来自使given
/when
像它一样工作的过程。
大多数情况下,
when(EXPR)
被视为$_
的隐式smart match。
...
答案 2 :(得分:0)
首先输出的预期行为是否无休止地匹配?因为这是该代码必须以其当前形式执行的操作。问题不在于智能匹配运算符。 while循环是无穷无尽的,因为$string
不会发生任何修改。 /g
全局开关不会改变循环本身。
你想要达到什么目的?我假设您要输出两位数值,每行一个。在这种情况下,您可能需要考虑:
say join("\n", grep { /^\d{2}$/ } split(" ",$string));
答案 3 :(得分:-1)
说实话,我不确定你可以使用智能匹配算子。在我的有限测试中,看起来智能匹配返回布尔值而不是匹配列表。但是,您发布的代码(使用=~
)可以在没有它的情况下工作
由于while
循环,您发布的内容无效。 while
循环上的条件语句在每次迭代开始之前执行。在这种情况下,正则表达式返回$string
中的第一个值,因为它在每次迭代时都会重置。但是foreach
会起作用:
my $string = '12 23 34 45 5464 46';
foreach my $number ($string =~ /(\d\d)\s/g) {
print $number."\n";
}