2008-09
05

今天讨论一下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位置匹配结束位置的偏移值不变

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




这篇文章有 4 条评论了,快来一起讨论讨论吧!
#1
longmans
2008-12-07 14:33

讲得好,还没有注意到有这么多学问呢

#2
charlee
2008-12-07 16:33

其实大骆驼书对这些细节问题讲了很多呢,就是平常看书时不容易注意到罢了

#3
cn2333333
2008-12-07 17:47

print “Hello, charlee!\n”;

就像作者所说的,PERL 90%用于处理文本,10%用于处理其他东西.

perl现在越来越引人注意了,很多公司都在用,多谢

请问能介绍下哪里有 Perl 相关的中文版资料看么?
书店太远了,懒得跑。呵呵

#4
charlee
2008-12-07 19:32

@cn2333333
推荐看小骆驼(《Perl语言入门》),大骆驼(《Perl语言编程》),《精通正则表达式》,《Perl最佳实践》。这些书在书店是买不到的,直接上网上书店去买,便宜又方便。不推荐读电子书,买这些书的钱绝对物有所值

添加评论