关于m//g的问题

来源:互联网 发布:css3动画和js动画 编辑:程序博客网 时间:2024/05/01 01:39

今天讨论一下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                重置为undef
m/.../g       字符串的pos位置              匹配结束位置的偏移值            重置为undef
m/.../gc      字符串的pos位置              匹配结束位置的偏移值                不变