Perl正则表达式超详细教程(5)

执行上述程序,将输出:

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,导致匹配失败,结束循环。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/e1a716f6fc1f35a6ad219d4af05ea1f5.html