2

如何使用 smartmatch 运算符 ( ~~) 编写此内容?

use 5.010;

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

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

4 回答 4

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吐槽:

Bareword 在 C:\Temp\y.pl 第 5 行找到操作员预期的位置,
“qr/(\d\d)\s/g”附近
C:\Temp\y.pl 第 5 行,“qr/(\d\d)\s/g”附近的语法错误

如果在上面的代码中使用了无效的表达式,大概它也应该说些什么

于 2009-10-28T15:40:55.283 回答
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是:

    -e 第 1 行,“qr/(.)/g”附近的语法错误


智能匹配功能从未打算取代=~操作员。它来自制作given/when工作的过程。

大多数时候,when(EXPR)被视为 的隐式智能匹配。 ...$_

于 2009-10-29T04:26:49.257 回答
0

输出的预期行为是否无休止地首先匹配?因为这就是该代码必须以当前形式执行的操作。问题不在于智能匹配运算符。while 循环是无止境的,因为从未对$string. /g全局开关不会改变循环本身。

你想达到什么目的?我假设您要输出两位数的值,每行一个。在这种情况下,您可能需要考虑:

say join("\n", grep { /^\d{2}$/ } split(" ",$string));
于 2009-10-29T02:37:53.727 回答
-1

老实说,我不确定您是否可以为此使用智能匹配运算符。在我有限的测试中,智能匹配似乎返回一个布尔值而不是匹配列表。但是,您发布的代码(使用=~)可以在没有它的情况下工作。由于循环
,您发布的内容不起作用。while循环上的条件语句在while每次迭代开始之前执行。在这种情况下,您的正则表达式将返回第一个值,$string因为它在每次迭代时都会被重置。但是Aforeach会起作用:

my $string = '12 23 34 45 5464 46';
foreach my $number ($string =~ /(\d\d)\s/g) {
    print $number."\n";
}
于 2009-10-29T20:34:51.060 回答