Perl中绑定运算符表达式的值

时间:2019-01-10 07:19:08

标签: regex 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的数组长度?

1 个答案:

答案 0 :(得分:3)

match运算符的返回取决于上下文:在列表上下文中,它返回所有捕获的匹配项,在标量上下文中,返回true / false。 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通常是错误,充其量是毫无意义的,或者是一个安静的错误。

请参见"Using regular expressions" in perlretut下的{<1}}中的“ 全局匹配”。 一般请参阅regex operators in perlop,也请参阅/gpos是探索/g运作方式的有用工具。