设为首页 加入收藏

TOP

Perl正则表达式引用(一)
2018-10-10 04:10:26 】 浏览:295
Tags:Perl 正则 表达式 引用

正则表达式两篇:


本文是对Perl正则的一点扩展,主要内容是使用qr//创建正则对象,以及一些其它的技巧。


qr//创建正则对象


因为可以在正则模式中使用变量替换,所以我们可以将正则中的一部分表达式事先保存在变量中。例如:
$str="hello worlds gaoxiaofang";
$pattern="w.*d";
$str =~ /$pattern/;
print "$&\n";


但是,这样缺陷很大,在保存正则表达式的变量中存放的特殊字符要防止有特殊意义。例如,当使用m//的方式做匹配分隔符时,不能在变量中保存/,除非转义。


perl提供了qr/pattern/的功能,它把pattern部分构建成一个正则表达式对象,然后就可以:


其中:


$str="hello worlds gaoxiaofang";


# 直接作为正则表达式
$str =~ qr/w.*d/;
print "$&\n";


# 保存为变量,再作为正则表达式
$pattern=qr/w.*d/;
$str =~ $pattern;    # (1)
$str =~ /$pattern/;  # (2)
print "$&\n";


# 保存为变量,作为正则表达式的一部分
$pattern=qr/w.*d/;
$str =~ /hel.* $pattern/;
print "$&\n";


还允许为这个正则对象设置修饰符,比如忽略大小写的匹配修饰符为i,这样在真正匹配的时候,就只有这一部分正则对象会忽略大小写,其余部分仍然区分大小写。
$str="HELLO wORLDs gaoxiaofang";


$pattern=qr/w.*d/i;        # 忽略大小写


$str =~ /HEL.* $pattern/;  # 匹配成功,$pattern部分忽略大小写
$str =~ /hel.* $pattern/;  # 匹配失败
$str =~ /hel.* $pattern/i;  # 匹配成功,所有都忽略大小写


qr如何构建正则对象


输出qr构建的正则引用,看看是怎样的结构:
$patt1=qr/w.*d/;
print "$patt1\n";


$patt2=qr/w.*d/i;    # 加上修饰符i
print "$patt2\n";


$patt3=qr/w.*d/img;  # 加上修饰符img
print "$patt3\n";


上面的print将输出如下结果:
(?^:w.*d)
(?^i:w.*d)
(?^mi:w.*d)


qr的作用实际上就是在我们给定的正则pattern基础上加上(?^:)并带上一些修饰符,得到的结果总是(?^FLAGS:pattern)。


但是上面patt3的修饰符g不见了。先可以看看(?^:)的作用:非捕获分组,并重置修饰符。重置为哪些修饰符?对于(?^FLAGS:)来说,只有这些修饰符"alupimsx"是可用的,即(?^alupimsx:):


所以上面的g会被丢弃,甚至在进一步操作这个正则引用时,会报错。


既然qr给pattern部分加上了(?^:),那么当它们插入到其它正则中的时候,就能保证这一段是独立的,不受全局修饰符影响的模式。
$patt1=qr/w.*d/im;
$patt2=qr/hel.*d $patt1/i;
print "$patt2\n";    # 输出:(?^i:hel.*d (?^mi:w.*d))


正则引用作为标量的用法


既然qr//创建的正则对象引用是一个标量,那么标量可以出现的地方,正则引用就可以出现。例如,放进hash结构,数组结构。


例如,放进数组中形成一个正则表达式列表,然后给定一个待匹配目标,依次用列表中的这些模式去匹配。
use v5.10.1;
my @patterns = (
    qr/(?:Willie )?Gilligan/,
    qr/Mary Ann/,
    qr/Ginger/,
    qr/(?:The )?Professor/,
    qr/Skipper/,
    qr/Mrs?. Howell/,
);


my $name = 'Ginger';
foreach my $pattern ( @patterns ) {
    if( $name =~ /$pattern/ ) {
        say "Match!";
        print "$pattern";
        last;
    }
}


还可以将这些正则引用放进hash中,为每个pattern都使用key来标识一下,例如pattern1是用来匹配什么的:
use v5.10.1;
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 $name = 'Ginger';
my( $match ) = grep { $name =~ $patterns{$_} } keys %patterns;
say "Matched $match" if $match;


上面将grep语句的结果赋值给了一个标量,所以如果有多个Pattern能匹配$name,多次执行,$match的值将可能会不一样。


构建复杂的正则表达式


有了qr,就可以将正则表达式细化成一小片一小片,然后组合起来。例如:
my $howells = qr/Thurston|Mrs/;
my $tagalongs = qr/Ginger|Mary Ann/;
my $passengers = qr/$howells|$tagalongs/;
my $crew = qr/Gilligan|Skipper/;
my $everyone = qr/$crew|$passengers/;


就像RFC 1738中对URL各个部分的解剖,如果转换成Perl正则,大概是这样的(了解即可):
# 可复用的基本符号类
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

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Perl正则表达式超详细教程 下一篇基础正则表达式详述

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目