我可以用Perl中的smartmatch操作符替换绑定操作符吗?

我可以用Perl中的smartmatch操作符替换绑定操作符吗?,perl,operators,smartmatch,Perl,Operators,Smartmatch,如何使用smartmatch操作符(~)编写此代码 有趣。国家: 任何~正则表达式模式匹配$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 看着,

如何使用smartmatch操作符(
~
)编写此代码

有趣。国家:

任何
~
正则表达式模式匹配
$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 看着,我们注意到

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" 在C:\Temp\y.pl第5行的运算符预期位置找到了Bareword, 靠近“qr/(\d\d)\s/g” C:\Temp\y.pl第5行“qr/(\d\d)\s/g”附近的语法错误
如果在上面的代码中使用了无效的表达式,那么它可能也会说一些话

预期的行为是无休止地输出到第一个匹配吗?因为这就是代码在当前形式下必须做的事情。问题不在于智能匹配操作符。while循环是无止境的,因为从未对
$string
进行任何修改。
/g
全局开关不会更改循环本身

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

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

如果我们去看看这两个变体被转化成了什么,我们就能看到原因


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

    perl -MO=Deparse -e'while("abc" =~ /(.)/g){print "hi\n"}'
    
    正如您所看到的,操作码没有任何变化

  • 现在,如果您将其更改为使用智能匹配操作符,您可以看到它确实发生了更改

    perl -MO=Deparse -e'while("abc" ~~ /(.)/g){print "hi\n"}'
    
    它将其更改为,不识别
    /g
    选项

    这可能会给您带来一个错误,但在解析它之前,它不会被转换


    您应该得到的警告是,如果改用,您将得到:

    syntax error at -e line 1, near "qr/(.)/g" -e第1行“qr/()/g”附近的语法错误

智能匹配功能从未打算取代
=~
运算符。它产生于像它那样工作的过程

大多数情况下,
当(EXPR)
被视为
$的隐式形式时


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

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

为什么这是家庭作业?如果是家庭作业呢?你具体需要智能匹配操作员做什么?“你想要什么还不清楚。”乔纳森,我已经老了@chollida满足好奇心。@Sinan所以我不能用智能匹配操作符写这个?@sid_com我不认为你可以,但我不知道这种行为是否是故意的。我猜你通过Deparse运行的东西中有一个bug。当我使用他输入的代码时,我得到以下信息:
while($string=~/(\d\d)\s/g)
。作为匹配的正则表达式(来自perlsyn),它应该有
g
操作符。我会检查你的perl安装=-[@Jack M.我通过Deparse运行的是我的帖子中显示的内容。我得到的输出是相同的。而且,我在Linux和Windows XP上用perl 5.10.1得到了相同的输出。这是我的错。我使用的是他的原始代码,而不是修改过的智能匹配代码。一旦你在智能匹配中出错,你是正确的。这是我的想法-用“~~”替换“=~”。Perl6是否只有智能匹配运算符,或者是否会有“=~”收件人?我尝试将“=~”更改为“~~”。但由于它不起作用,我将使用“=~”。完全错误且不恰当。首先,在
while
循环中使用
$string=~s///g
,不仅完全可以,而且在许多情况下比
for
循环更好。其次,您忽略了一个事实,即OP谈论的是智能匹配操作符
~
,而不是
=
。他没有使用
s///g
。他基本上使用的是
m///g
。你对智能操作符的看法是正确的,我会编辑以修正这一点。我的意思是
m///code>,我所说的
s///code>适用于
中的
m///code>,而
相比,同样适用于
循环。除非你正在操作(在这种情况下)
$string
在循环中,你不是在创建一个无限循环吗?在OP的问题中,这就是为什么他的代码没有输出他所期望的,不是吗?不。你不是在创建一个无限循环,正是因为
g
修饰符。请尝试
while($string=~/(\d{2})\s/g){print“$1\n}
while(m//g)
for(m//g)
之间的区别在于,您可以在
while
中逐个操作匹配项(就像逐行读取文件,而不是逐行读取文件)。
perl -MO=Deparse -e'while("abc" ~~ /(.)/g){print "hi\n"}'
while ('abc' ~~ qr/(.)/g) {
    print "hi\n";
}
syntax error at -e line 1, near "qr/(.)/g"
my $string = '12 23 34 45 5464 46';
foreach my $number ($string =~ /(\d\d)\s/g) {
    print $number."\n";
}