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 \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标记告诉正则记录每次成功匹配都在何处完成匹配;

壹陆贰.

利用表格建立正则表达式。

# 建立模式以匹配任何下列不规则复数……

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’;

PerlIO::via::QuotedPrint是Perl语言中的一个模块,用于在文件读写时对数据进行Quoted-Printable编码和解码。Quoted-Printable是一种用于在ASCII字符集中表示非ASCII字符的编码方式,常用于电子邮件和网络传输中。PerlIO::via::QuotedPrint模块提供了一种方便的方式,可以在文件读写时对数据进行Quoted-Printable编码和解码。 PerlIO::via::QuotedPrint模块的使用方法与其他PerlIO模块类似。可以使用open函数打开一个文件句柄,并指定PerlIO::via::QuotedPrint模块作为过滤器,从而实现对文件数据的编码和解码。 下面是一个使用PerlIO::via::QuotedPrint模块对文件进行Quoted-Printable编码和解码的例子: ``` use PerlIO::via::QuotedPrint; # Quoted-Printable编码 open(my $fh, '>:via(QuotedPrint)', 'file.txt'); print $fh "这是一段中文文本\n"; close($fh); # Quoted-Printable解码 open(my $fh, '<:via(QuotedPrint)', 'file.txt'); while(my $line = <$fh>) { print $line; } close($fh); ``` 在上面的例子中,我们使用了PerlIO::via::QuotedPrint模块对一个文件进行了编码和解码。在第一个open函数中,我们使用了':via(QuotedPrint)'指定了PerlIO::via::QuotedPrint模块作为过滤器,从而将写入文件的数据进行了Quoted-Printable编码。在第二个open函数中,我们同样使用了':via(QuotedPrint)'指定了PerlIO::via::QuotedPrint模块作为过滤器,从而将读取的数据进行了Quoted-Printable解码。 使用PerlIO::via::QuotedPrint模块可以方便地对文件数据进行Quoted-Printable编码和解码,从而满足不同应用场景中对数据编码的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值