Perl 最佳实践(节选) --- 12
? 第十二章:正则表达式? 正则表达式就是子程序。就是文本匹配子程序。 ? ? ? 壹肆伍.一定要用/x标记。 ? ? ? 壹肆陆.一定要用/m标记。 ? ? ? 壹肆柒.以A和z作为字符串边界锚点(anchor)。 ? ?????? #删除前后空白…… ?????? $text=~ s{A s* | s* z}{}gxm; ? ? ? 壹肆捌.使用z表示“字符串末尾”,不要用Z。 ? Perl提供z标示符号的变形版本:Z。但是,小写z是指“匹配字符串末尾”,而大写Z是指“匹配可有可无的换行字符,然后是字符串末尾”。 ? ? ? 壹肆玖.总是使用/s标记。 ? ? ? 壹伍零.考虑强制使用Regexp::Autoflags模块。 ? 为了我们在每个正则后面少输入“/xms”,我们可以使用: ?????? useRegexp::Autoflags; ? ? ? 壹伍壹.优先使用m{…},少在多行正则表达式中用/…/。 ? ? ? 壹伍贰.除了/…/或m{…}以外,不要用其他定界符。 ? ? ? 壹伍叁.最好使用字符类,不用转义的元字符(metacharacter)。 ? ? ? 壹伍肆.最好使用具名字符,不用转义的元字符。 ? 例如: ?????? if($escape_seq =~ /177 06 30 Z/xms) {????? #Octal DEL-ACK-CAN-Z ????????????? blink(182); ?????? } ? ?????? 改写为: ?????? usecharnames qw( :full); ?????? ?????? if($escape_seq =~ m/N{DELETE} N{ACKNOWLEDGE} N{CANCEL} Z/xms) { ????????????? blink(182); ?????? } ? ? ? 壹伍伍.最好使用特性(property),而不用枚举式字符类。 ? ?????? Readonly my $ALPHA_IDENT => qr/ p{Uppercase}p{Alphabetic}* /xms; ? 注Perl5.8以上版本才支持Unicode。 ? ? ? 壹伍陆.考虑匹配任意空白,而不是特定空白字符。 ? ?????? $config_line=~ m{ ($IDENT)? s*???? =???? s*?? (.*) }xms ? ? ? 壹伍柒.当匹配“尽可能多”时,一定要制定。 ? ?????? #格式为:<source>% <data> & <config> …… ?????? if($source =~ m/A????????????? ([^%]*)?? %??? ([^&]*)?? &??? (.*)? /xms) { ????????????? my($statements,$data,$config) = ($1,$2,$3); ? ????????????? my$prog = compile($statements,{config=>$config}); ????????????? my$res = execute($prog,??? {data=>$data,config=>$config}); ?????? } ?????? else{ ????????????? croak????? ‘Invalid program’; ?????? } ? 正则的最后“.*?”不是多余的,就是未做你想要做的事,或者是你忘了一个z锚点。 ? ? ? 壹伍捌.只有当你要捕获时,才使用捕获小括号。 ? ? ? 壹伍玖.只有当你确定前次匹配成功时,才使用数值式的捕获变量。 ? 数值式的捕获变量:$1,$3… ? ? ? 壹陆零.一定要给予捕获的子字符串适当的名称。 ? $myName = $1; ? ? ? 壹陆壹.使用/gc标记把输入字符串记号化(tokenize)。 ? /gc标记告诉正则记录每次成功匹配都在何处完成匹配; ? ? ? 壹陆贰.利用表格建立正则表达式。 ? #???? 建立模式以匹配任何下列不规则复数…… ?????? my$has_irregular_plural ????????????? =join ‘|’,map {quotemeta $_} reverse sort keys %irregular_plural_of; ? ? ? 壹陆叁.由较简单的零件建立复杂的正则表达式。 ? # 建立正则表达式以匹配浮点数…… ?????? Readonlymy $DIGITS???????? => qr{??? d+? (?:? [.]?d*)?? |? [.]?d+??????? ?????? }xms; ?????? Readonlymy $SIGN???????????? => qr{??? [+-]????????????????????????????????????????????????? ?????? }xms; ?????? Readonlymy $EXPONENT?? => qr{??? [Ee]??????? $SIGN?????????? d+??????????????? ?????? }xms; ?????? Readonly my $NUMBER?????? =>qr{??? ( ?($SIGN?)?($DIGITS)? ($EXPONENT)}xms; ? ?????? #稍后…… ?????? my($number,$sign,$digits,$exponent) ????????????? =$input =~ $NUMBER; ? ? ? 壹陆肆.考虑使用Regexp::Common,不要自己写正则表达式。 ? ? ? 壹陆伍.使用字符类,不要使用单一字符交替(alternation)。 ? if ($quotelike!~ m{A??? (?:? q[qrx]?|? [gsy]? |?tr? )? z}xms) { ?????? carp “Unknown quotelike: $quotelike”; ????????????? nextQUOTELIKE; ?????? } ? ? ? 壹陆陆.从交替选择中把共同的词缀分离出来。 ? ? ? 壹陆柒.避免无用的回溯。 ? ? ? 壹陆捌.最好用固定字符串的eq比较,不要用固定模式的正则表达式匹配。 ? # 离开命令有很多变形版本 …… ?????? lastCOMMAND if $cmd =~ m{A? (?:? q?|? quit? |?bye)}xms; ? ? # 离开命令有很多变形版本 …… ?????? lastCOMMAND if $cmd eq? ?‘q’ ||? $cmd eq?‘quit’ ||? $cmd eq? ‘bye’; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |