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

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

问题描述:

如何使用smartmatch操作符(~~)将其写入?我可以使用Perl中的smartmatch运算符替换绑定运算符吗?

use 5.010; 

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

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

这功课吗? – 2009-10-28 15:08:05

+0

为什么这是作业?如果这是作业呢? – innaM 2009-10-28 15:13:28

+1

你需要什么具体的匹配运算符来做?目前还不清楚你想要什么。 – chollida 2009-10-28 15:14:20

如果我们去看看这两个变体是如何转换的,我们可以看到原因。


  • 首先让我们看一下原始版本。

    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
...

+0

这是我的想法 - 用“~~”替换“=〜”。 Perl6是否只有智能匹配运算符或会有“=〜”? – 2009-10-29 18:05:08

有趣。 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" 

想必也应该说些什么,如果一个无效的表达式是在代码中使用上述

+0

@Sinan所以我不能用智能匹配运算符写这个吗? – 2009-10-28 16:21:17

+1

@sid_com我不认为你可以,但我不知道这种行为是否由设计。 – 2009-10-28 16:25:54

+0

我猜你在跑过Deparse的地方存在一个错误。当我使用他输入的代码时,我得到:'while($ string =〜/(\ d \ d)\ s/g)'。作为一个匹配的正则表达式(来自perlsyn),它应该有'g'运算符。我会检查你的perl安装。 = - [ – 2009-10-29 20:42:14

是的预期的行为输出到无尽的第一场比赛?因为这是这个代码必须以当前形式做的事情。问题不在于智能匹配运算符。 while循环是无止境的,因为$string没有发生任何修改。全局开关/g不会更改环路本身。

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

say join("\n", grep { /^\d{2}$/ } split(" ",$string)); 
+0

我试图用“~~”来改变“=〜”。但由于它不起作用,我会使用“=〜”。 – 2009-10-29 18:06:30

说实话,我不知道,你可以使用智能匹配运营商这一点。在我有限的测试中,它看起来像智能匹配是返回一个布尔值而不是匹配列表。但是,您发布的代码(使用=~)无法使用它。
由于while循环,您发布的内容不起作用。在每次迭代开始之前执行while循环上的条件语句。在这种情况下,您的正则表达式会返回$string中的第一个值,因为它在每次迭代时都会重置。 A foreach可以工作:

my $string = '12 23 34 45 5464 46'; 
foreach my $number ($string =~ /(\d\d)\s/g) { 
    print $number."\n"; 
} 
+0

完全错误并且不合格。首先,在'while'循环中使用'$ string =〜s /// g'不仅非常好,而且在很多情况下比'for'循环更可取。其次,你错过了OP正在谈论智能匹配运算符'~~'而不是'=〜'的事实。 – 2009-10-29 20:58:30

+0

虽然他没有使用/// g'。他基本上使用'm /// g'。你对智能操作员是正确的,我会编辑修复这一点。 – 2009-10-29 21:04:48

+0

我的意思是'm //',而我对'///'所说的内容适用于'while'和'for'循环中的'm //'。 – 2009-10-29 21:34:27