Regex perl中绑定运算符表达式的值

Regex perl中绑定运算符表达式的值,regex,perl,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]/

我对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,这是数组的长度?

匹配运算符的返回取决于上下文:在列表上下文中,它返回所有捕获的匹配,在标量上下文中,它返回真/假。say强制使用列表上下文,但在第一个示例中,regex中没有捕获任何内容,因此只能获得“success”

接下来,
/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
通常是一个错误,充其量是毫无意义的,或者是一个安静的bug

有关
/g
,请参见下面的“全局匹配”。
请参见概述,以及关于
/g
。探索
/g
工作的有用工具是。

非常感谢您的解释。我以前对
/g
修饰符的看法确实非常错误。感谢您澄清
/g
和这些上下文内容。@user15964最受欢迎:)。由于上下文相关的行为,
/g
确实很棘手。(如果您想播放并了解它的功能,那么一个有用的工具是什么。)一般来说,上下文是Perl中的关键概念之一,实际上是不可避免的。