我可以用Perl中的smartmatch运算符替换绑定运算符吗?

时间:2009-10-28 15:05:14

标签: perl operators smartmatch

如何使用smartmatch运算符(~~)编写此代码?

use 5.010;

my $string = '12 23 34 45 5464 46';

while ( $string =~ /(\d\d)\s/g ) {
    say $1;
}

4 个答案:

答案 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;
}

打印1223等,但它会陷入循环,重复匹配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";
}