首页 > 解决方案 > perl中绑定运算符表达式的值

问题描述

我对 perl 中绑定运算符表达式的结果有些怀疑。我的意思是像这样的表达

string =~ /pattern/

我做了一些简单的测试

$ss="a1b2c3";
say $ss=~/a/;   # 1
say $ss=~/[a-z]/g;  # abc
@aa=$ss=~/[a-z]/g;say @aa;  # abc
$aa=@aa;say $aa;    # 3
$aa=$ss=~/[a-z]/g;say $aa;  # 1

注意上面的注释部分是运行结果。

所以问题来了,到底是什么返回的$ss=~/[a-z]/g,似乎根据代码行3、4、5返回了一个数组。但是最后一行呢,为什么它给出 1 而不是 3 数组的长度呢?

标签: regexperl

解决方案


匹配运算符的返回取决于上下文:在列表上下文中它返回所有捕获的匹配项,在标量上下文中返回真/假。say强加列表上下文,但在第一个示例中,正则表达式中没有捕获任何内容,因此您只能获得“成功” 。

接下来,/g修饰符的行为也因上下文而异。在列表上下文中,使用给定模式继续扫描字符串,直到找到所有匹配项,并返回包含它们的列表。这是你的第二个和第三个例子。

但在标量上下文中,它的行为有点具体:搜索将从最后一次匹配的位置继续,下一轮。一种典型的用途是在循环条件下

while (/(\w+)/g) { ... }

这有点像分词器:在循环体运行之后,找到下一个单词,等等。

那么最后一个例子就没有意义了;你得到“正常”的标量上下文匹配成功/失败,并且/g不做任何事情——直到你$ss下次匹配

perl -wE'
    $s=shift||q(abc); 
    for (1..2) { $m = $s=~/(.)/g; say "$m: $1"; }
'

打印行1:a,然后1:b.

在迭代结构(如while条件)之外/g,标量上下文通常是一个错误,充其量是毫无意义的或安静的错误。

请参阅perlretut 中“使用正则表达式”下的“全局匹配”以获取. 一般参见perlop中的正则表达式运算符,以及大约。探索工作原理的一个有用工具是pos/g/g/g


推荐阅读