標籤:
第十二章:Regex
Regex就是子程式。就是文本匹配子程式。 壹肆伍.
一定要用/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{…},少在多行Regex中用/…/。 壹伍貳.
除了/…/或m{…}以外,不要用其他定界符。 壹伍三.
最好使用字元類,不用轉義的元字元(metacharacter)。 壹伍肆.
最好使用具名字元,不用轉義的元字元。
例如:
if($escape_seq =~ /\177 \006 \030 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,$2,$3… 壹陸零.
一定要給予捕獲的子字串適當的名稱。
$myName = $1; 壹陸壹.
使用/gc標記把輸入字串記號化(tokenize)。
/gc標記告訴正則記錄每次成功匹配都在何處完成匹配; 壹陸貳.
利用表格建立Regex。
# 建立模式以匹配任何下列不規則複數……
my$has_irregular_plural
=join ‘|’, map {quotemeta $_} reverse sort keys %irregular_plural_of; 壹陸三.
由較簡單的零件建立複雜的Regex。
# 建立Regex以匹配浮點數……
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,不要自己寫Regex。 壹陸伍.
使用字元類,不要使用單一字元交替(alternation)。
if ($quotelike!~ m{\A (?: q[qrx] | [gsy] | tr ) \z}xms) {
carp “Unknown quotelike: $quotelike”;
nextQUOTELIKE;
} 壹陸陸.
從交替選擇中把共同的詞綴分離出來。 壹陸柒.
避免無用的回溯。 壹陸捌.
最好用固定字串的eq比較,不要用固定模式的Regex匹配。
# 離開命令有很多變形版本 ……
lastCOMMAND if $cmd =~ m{\A (?: q | quit | bye)}xms;
# 離開命令有很多變形版本 ……
lastCOMMAND if $cmd eq ‘q’
|| $cmd eq ‘quit’
|| $cmd eq ‘bye’;
Perl 最佳實務(節選) --- 12