[Perl]关于m//g的问题

来源:互联网 发布:2017单片机就业方向 编辑:程序博客网 时间:2024/05/21 20:41

今天讨论一下m//g一个的小问题。m//g表示在字符串中查找所有可能出现的模式匹配。在标量环境下,m//g会依次查找每个出现的匹配。通常的用法是这样的:

while (/(pattern)/g) {
print $1; # 做些操作
}

在内部,m//g会保存一个“匹配位置”的变量,表示这次的m//g匹配到了什么位置,以便下次运行时从该处继续开始。(这个位置可以通过pos函数获得,这里就不多说了。)通常,用在while循环里是没有任何问题的,但如果换成if会怎样?

$_ = "abc";
print "a" if /a/g;
print "b" if /b/g;
# 输出结果:ab

结果是正确的。如果将语句换个位置呢?

$_ = "abc";
print "b" if /b/g;
print "a" if /a/g;
# 输出结果:b

可见,第二次的模式 a 没有匹配。其实可以想到,第一次的m/b/g匹配后,匹配位置已经指向了字符串中的下一个位置c,第二行的m/a/g继续从c开始匹配,当然不会匹配到任何东西。

借用一下《精通正则表达式》第7章对于Match运算符的说明:

匹配类型尝试开始位置匹配成功时的pos值匹配失败时的pos值m/.../字符串起始位置(忽略pos)重置为undef重置为undefm/.../g字符串的pos位置匹配结束位置的偏移值重置为undefm/.../gc字符串的pos位置匹配结束位置的偏移值不变

话说回来,在if中使用/g选项是毫无意义的。这里只是提个醒,当你遇到诡异的无法匹配的问题时,别忘了是不是在if中使用了m//g。

原创粉丝点击