1. 从Perl 5.5 开始 引入了新的quoing机制 --〉qr// 操作符,提供一个编译后的正则表达式引用给我们
my $regex = qr/Gilligan|Skipper/;
2. qr// 操作符不能解决非法模式的问题,我们仍需要使用eval如果我们使用字符串内插的话
my $regex = eval {qr/$pattern/};
3. 我们也可以使用其它的分界符
my $regex = qr(/usr/local/bin/\w+);
4. 如果用单引号作为分界符,那么Perl不会进行字符串内插
my $regex = qr'$var'; # 这代表四个字符
5. 以单引号为分界符,正则表达式元字符还是生效的,所以如果要匹配字面的$, 需要反斜线转义
my $regex = qr'\$\d+\.\d+';
6. 使用qr// 我们只能添加影响模式的标志位,有如下两种方式
1) qr/Gilligan$/mi;
2) qr/(?mi:Gilligan)/; # 在模式中直接添加标志位
7. 应用正则表达式引用时,我们既可以像传统方式那样内插到匹配或替换操作符中,如
my $regex = qr/Gilligan/;
$string =~ m/$regex/;
$string =~ s/$regex/Skipper/;
也可以直接使用到bind操作符或智能匹配中,如
$string =~ $regex;
$string ~~ $regex;
8. 一个完整的例子
use v5.12;
sub rightmost {
my( $string, @patterns ) = @_;
my $rightmost = -1;
while( my ($i, $pattern) = each @patterns) {
my $position = $string =~ m/$pattern/ ? $-[0] : -1; # 特殊变量@-记录匹配的起始位置和捕获组,$-[0]就记录起始位置,对应的$+[0]记录结束位置
$rightmost = $position if $position > $rightmost;
}
return $rightmost;
}
my %patterns = (
Gilligan => qr/(?:Willie )?Gilligan/,
'Mary Ann' => qr/Mary Ann/,
Ginger => qr/Ginger/,
Professor => qr/(?:The )?Professor/,
Skipper => qr/Skipper/,
'A Howell' => qr/Mrs?. Howell/,
);
my $position = rightmost(
'There is Mrs. Howell, Ginger, and Gilligan',
@patterns{ sort keys %patterns } # 此处是利用hash切片获取由已排序的hash键组成的数组
);
say "Rightmost match at position $position";
9. 使用正则表达式引用构造各种表达式的例子
my $alpha = qr/[a−z]/;
my $digit = qr/\d/;
my $alphadigit = qr/(?i:$alpha|$digit)/;
my $safe = qr/[\$_.+−]/;
my $extra = qr/[!*'\(\),]/;
my $national = qr/[{}|\\^~\[\]`]/;
my $reserved = qr|[;/?:@&=]|;
my $hex = qr/(?i:$digit|[A−F])/;
my $escape = qr/%$hex$hex/;
my $unreserved = qr/$alpha|$digit|$safe|$extra/;
my $uchar = qr/$unreserved|$escape/;
my $xchar = qr/$unreserved|$reserved|$escape/;
my $ucharplus = qr/(?:$uchar|[;?&=])*/;
my $digits = qr/(?:$digit){1,}/;
my $hsegment = $ucharplus;
my $hpath = qr|$hsegment(?:/$hsegment)*|;
my $search = $ucharplus;
my $scheme = qr|(?i:https?://)|;
my $port = qr/$digits/;
my $password = $ucharplus;
my $user = $ucharplus;
my $toplevel = qr/$alpha|$alpha(?:$alphadigit|−)*$alphadigit/;
my $domainlabel = qr/$alphadigit|$alphadigit(?:$alphadigit|−)*$alphadigit/x;
my $hostname = qr/(?:$domainlabel\.)*$toplevel/;
my $hostnumber = qr/$digits\.$digits\.$digits\.$digits/;
my $host = qr/$hostname|$hostnumber/;
my $hostport = qr/$host(?::$port)?/;
my $login = qr/(?:$user(?::$password)\@)?/;
my $urlpath = qr/(?:(?:$xchar)*)/;
10. 一些常用的正则表达式,我们不需要自己写,已经有高人封装为module,我可以直接使用。Regexp::Common由Abigail编写,它输出一个名为$RE的hash引用,例子:
use v5.10.1;
use Regexp::Common qw(net);
while( <> ) {
say if /$RE{net}{IPv4}/;
}
use v5.10.1;
use Regexp::Common qw(number);
while( <> ) {
say if /$RE{num}{int}/;
}
11. 用Regexp::Assemble组装正则表达式, 它可以优化正则表达式的写法,例子
use v5.10.1;
use Regexp::Assemble;
my $ra = Regexp::Assemble−>new;
for ( 'Mr. Howell', 'Mrs. Howell', 'Mary Ann' ) {
$ra−>add( "\Q$_" );
}
say $ra−>re; # (?^:M(?:rs?\. Howell|ary Ann))
如果使用的Perl 5.10或更高版本,Perl也会为我们做这项工作(正则表达式优化)