执行上述程序,将输出:
matched 12: 2 matched 34: 4 matched 34: 4 matched 5: 6 matched 6: 7 matched 6: 7继续上面的问题,如果第三个匹配语句不是\d\d\d,而是"\d",它匹配字母a的时候也失败,不用c修饰符的时候会重置位移吗?显然是不会。因为它会继续向后匹配。所以该\G登场了。
默认全局匹配情况下,匹配时是可以跳过匹配失败的字符继续匹配的:当某个字符匹配失败,它会后移一位继续去匹配,直到匹配成功或匹配结束。
$txt="1234ab56"; $txt =~ /\d\d/g; print "matched $&: ",pos $txt,"\n"; $txt =~ /\d\d/g; print "matched $&: ",pos $txt,"\n"; $txt =~ /\d/g; # 字母a匹配失败,后移一位,字母b匹配失败,后移一位,数值5匹配成功 print "matched $&: ",pos $txt,"\n"; $txt =~ /\d/g; # 数值6匹配成功 print "matched $&: ",pos $txt,"\n";执行上述程序,将输出:
matched 12: 2 matched 34: 4 matched 5: 7 matched 6: 8可以指定\G,使得本次匹配强制从位移处进行匹配,不允许跳过任何匹配失败的字符。
如果本次\G全局匹配成功,位移指针自然会后移
如果本次\G全局匹配失败,且没有加上c修饰符,那么位移指针将重置
如果本次\G全局匹配失败,且加上了c修饰符,那么位移指针将卡在那不动
例如:
$txt="1234ab56"; $txt =~ /\d\d/g; print "matched $&: ",pos $txt,"\n"; $txt =~ /\d\d/g; print "matched $&: ",pos $txt,"\n"; $txt =~ /\G\d/g; # 强制从位移4开始匹配,无法匹配字母a,但又不允许跳过 # 所以本次\G全局匹配失败,由于没有修饰符c,指针重置 print "matched $&: ",pos $txt,"\n"; $txt =~ /\G\d/g; # 指针回到0,强制从0处开始匹配,数值1能匹配成功 print "matched $&: ",pos $txt,"\n";以下是输出内容:
matched 12: 2 matched 34: 4 matched 34: matched 1: 1如果将上面第三个匹配语句加上修饰符c,甚至后面的语句也都加上\G和c修饰符,那么位移指针将卡在那个位置:
$txt="1234ab56"; $txt =~ /\d\d/g; print "matched $&: ",pos $txt,"\n"; $txt =~ /\d\d/g; print "matched $&: ",pos $txt,"\n"; $txt =~ /\G\d/gc; # 匹配失败,指针卡在原地 print "matched $&: ",pos $txt,"\n"; $txt =~ /\G\d/gc; # 匹配失败,指针继续卡在原地 print "matched $&: ",pos $txt,"\n"; $txt =~ /\G\d/gc; # 匹配失败,指针继续卡在原地 print "matched $&: ",pos $txt,"\n";以下是输出结果:
matched 12: 2 matched 34: 4 matched 34: 4 matched 34: 4 matched 34: 4一般来说,全局匹配都会用循环去多次迭代,和上面一次一次列出匹配表达式不一样。所以,下面使用while循环的例子来对\G和c修饰符稍作解释,其实理解了上面的内容,在循环中使用\G和c修饰符也一样很容易理解。
$txt="1234ab56"; while($txt =~ m/\G\d\d/gc){ print "matched: $&, ",pos $txt,"\n"; }执行结果:
matched: 12, 2 matched: 34, 4当第三轮循环匹配到a字母的时候,由于使用了\G,导致匹配失败,结束循环。