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