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

上面使用c与否是无关紧要的,但如果这个while循环的后面后还有对$txt的匹配,那么使用c修饰符与否就有关系了。例如下面两段程序,返回结果不一样:

$txt="1234ab56"; while($txt =~ m/\G\d\d/gc){ # 使用c修饰符 print "matched: $&, ",pos $txt,"\n"; } $txt =~ m/\G\d\d/gc; print "matched: $&, ",pos $txt,"\n";

$txt="1234ab56"; while($txt =~ m/\G\d\d/g){ # 不使用c修饰符 print "matched: $&, ",pos $txt,"\n"; } $txt =~ m/\G\d\d/gc; print "matched: $&, ",pos $txt,"\n"; m修饰符:多行匹配模式

正则表达式一般都只用来匹配单行数据,但有时候却需要一次性匹配多行。比如匹配跨行单词、匹配跨行词组,匹配跨行的对称分隔符(如一对括号)。

使用m修饰符可以开启多行匹配模式。

例如:

$txt="ab\ncd"; $txt =~ /a.*\nc/m; print "===match start===\n$&\n===match end===\n";

执行,将输出:

===match start=== ab c ===match end===

关于多行匹配,需要注意的是元字符.默认情况下无法匹配换行符。可以使用[\d\D]代替点,也可以开启s修饰符使得.能匹配换行符。

例如,下面两个匹配输出的结果和上面是一致的。

$txt="ab\ncd"; $txt =~ /a.*c/ms; print "===match start===\n$&\n===match end===\n"; $txt="ab\ncd"; $txt =~ /a[\d\D]*c/m; print "===match start===\n$&\n===match end===\n"; s修饰符

默认情况下,.元字符是不能匹配换行符\n的,开启了s修饰符功能后,可以让.匹配换行符。正如刚才的那个例子:

$txt="ab\ncd"; $txt =~ /a.*c/m; # 匹配失败 print "===match start===\n$&\n===match end===\n"; $txt="ab\ncd"; $txt =~ /a.*c/ms; # 匹配成功 print "===match start===\n$&\n===match end===\n"; x修饰符

正则表达式最为人所抱怨的就是它的可读性极差,无论你的正则能力有多强,看着一大堆乱七八糟的符号组合在一起,都得一个符号一个符号地从左向右读。

万幸,perl正则支持表达式的分隔,甚至支持注释,只需加上x修饰符即可。这时候正则表达式中出现的所有空白符号都不会当作正则的匹配对象,而是直接被忽略。如果想要匹配空白符号,可以使用\s表示,或者将空格使用\Q...\E包围。

例如,以下4个匹配操作是完全等价的。

$ans="cat sheep tiger"; $ans =~ /(\w) *(\w) *(\w)/; # 正常情况下的匹配表达式 $ans =~ /(\w)\s* (\w)\s* (\w)/x; $ans = ~ / (\w)\s* # 可以加上本行注释:匹配第一个单词 (\w)\s* # 可以加上本行注释:匹配第二个单词 (\w) # 可以加上本行注释:匹配第三个单词 /x; $ans =~ / (\w)\Q \E # \Q \E强制将中间的空格当作字面符号被匹配 (\w)\Q \E (\w) /x;

对于稍微复杂一些的正则表达式,常常都会使用x修饰符来增强其可读性,最重要的是加上注释。这一点真的非常人性化。

p修饰符

前面说过,通过3个特殊变量$`、$&和$'可以保存匹配内容之前的内容,匹配内容以及匹配内容之后的内容。但是,只要使用了这3个变量中的任何一个,后面的所有分组效率都会降低。perl提供了一个p修饰符,能实现完全相同的功能:

${^PREMATCH} <=> $` ${^MATCH} <=> $& ${^POSTMATCH} <=> $'

���个例子即可描述:

$ans="cat sheep tiger"; $ans =~ /sheep/p; print "${^PREMATCH}\n"; # 输出"cat " print "${^MATCH}\n"; # 输出"sheep" print "${^POSTMATCH}\n"; # 输出" tiger" o修饰符

在较老的perl版本中,如果使用同一个正则表达式做多次匹配,正则引擎将只多次编译正则表达式。很多时候正则表达式并不会改变,比如循环匹配文件中的行,这样的多次编译导致性能下降很明显,于是可以使用o修饰符让正则引擎对同一个正则表达式不重复编译。

在perl5.6中,默认情况下对同一正则表达式只编译一次,但同样可以指定o修饰符,使得即使正则表达式变化了也不要重新编译。

一般情况下,可以无视这个修饰符。

范围模式匹配修饰符(?imsx-imsx:pattern)

前文介绍的修饰符adluoimsxpngc都是放在m//{FLAG}的flag处的,放在这个位置会对整个正则表达式产生影响,所以它的作用范围有点广。

例如m/pattern1 pattern2/i的i修饰符会影响pattern1和pattern2。

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

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