perl学习日记8正则表达式的应用

 

1.1      使用m//匹配

这是m//(模式匹配)的一种简写。同qw//操作一样,可以使用任何成对的分隔符。因此,可以使用m(fred)m<fred>m{fred}m[fred],或者m,fred,m!fred!m^fred^,其它非成对的分隔符也可以。

如果使用正斜线(/)作为分隔符,则可以省略掉前面的m。这就是前面用的最多的。

 

尽量使用一个不会在模式中出现的字符作为分隔

1.2      可选的修饰符

1.2.1.      不区分大小写:/i

1.2.2.      匹配任何字符:/s

 

默认情况下,点(.)不匹配换行符,这对于单行中查找的问题能很好解决。如果你的字符串中有换行符,并希望点(.)能匹配它们,那可以使用/s 这个修饰符。

$_ = “I saw Barney/ndown at the bowing alley/nwith Fred/nlast night./n”;

if(/Barney.*Fred/s){

print “That string mentions Fred after Barney!/n”;

}

1.2.3.      添加空格:/x

/-?/d+/.?/d*/ #这是什么含义?

/ -? /d+ /.? /d* /x #要好些

 

主要就是增加可读性,但不改变语义

1.2.4.将可选字符结合起来

if(/barney.*fred/is){ # /i /s 书上写错了,多了一个(/)

print “That string mentions Fred after Barney!/n”;

}

1.3      锚定

模式/^fred/只匹配字符串的开头部分;它不会匹配上manfred man。而/rock$/只在结尾处匹配;其不会匹配上knute rockne

 

在模式中^,有其它的用途。在字符类中,如果将其放在最前面,将会得到此集合的补集。

 

记住/^fred$/能同时匹配上fredfred/n

 

注意是整个字符串的结尾和开头,不是某个单词的结尾我开头。

 

有时,想同时使用这两个锚定来确保匹配整个字符串。一个经常使用的例子是/^/s*$/,它将匹配一个空行(blank line)。这里的“blank(空白),可以是空白符,如制表符,空格等,它们是不可见的。能被匹配上的行看起来都是一样的,因此这个模式将所有的空白按一种方法来处理。如果没有锚定,则它还会匹配上非空行。

1.3.1.词锚定

词界锚定,/b,是针对单词使用的。如//bfred/b/可以匹配上单词fred,但不能匹配frederick,

Alfred

 

词是字母,数字,下划线组成的序列。这种意义下的词可由//w+/匹配上。下句中有个词:That,s,a,word,以及boundary。词上的引号不会改变词界的位置;这些词是由/w 字符组成的。

 

以上划线的就是“词” /b 只匹配这样的词

 

当使用//bhunt/ 将匹配上像hunthuntinghunter,这样的单词,但不会匹配shunt,而/stone/b/将匹配sandstoneflintstone,而不能匹配上capstones

1.4      绑定操作符,=~

my $some_other = “I dream of betty rubble.”;

if($some_other =~ //brub/){

print “Aye, there’s the rub./n”;

}

其含义是:“这个模式默认将对$_进行匹配,但此时将对左边的字符串进行匹配”。

 

print “Do you like Perl? ”;

my $likes_perl = (<STDIN> =~ //byes/b/i);

… #Times passes…

if($likes_perl){

print “You said earlier that you like Perl, So… /n”;

}

 

my $likes_perl = <STDIN> =~ //byes/b/i;    #一样正确,因为~的优先级高

1.5      模式内的内插

#! /usr/bin/perl –w

my $what = “larry”;

while(<>){

if(/^($what)/){ #在字符串前面进行匹配

print “We saw $what in beginning of $_;”;

}

 

也可以从程序参数读取模式

my $what = shift @ARGV;

 

/^(fred|barney)/:在行首查找fred 或者barney。括号(在查找larry 的例子中不是必须的)是非常重要的,如果没有它,则在行首查找fred,或在此行中任意位置查找barney

如果$wha的值为fred(barney,这个模式是/^(fred(barney)/。上述模式是不能工作的,会由于错误使用正则表达式而使程序垮掉。

 

1.6      匹配变量

$_ = “Hello there, neighbor”;

if(//s(/w+),/){ #空格和逗号之间的词

print “the word was $1/n”; #the word was there

}

 

$_ = “Hello there, neighbor”;

if(/(/S+) (/S+), (/S+)/){

print “words were $1 $2 $3”;

}

其输出为words were Hello there neighbor

 

my $dino = "I fear that I'll be extinct after 1000 years.";

if ($dino =~ /(/d*) years/) {

print "That said '$1' years./n"; # 1000

}

my $dino = "I fear that I'll be extinct after a few millions years.";

if ($dino =~ /(/d*) years/) {

print "That said '$1' years./n"; # 空串     暂没弄清楚为啥$1有单引号,如果打印$2会怎样?是不是因是undef而显示(哈批,因为它想打印单引号出来,$2也是打印空串)

}

 

1.6.1.内存值的保存

这些匹配变量的值会保持不变,直到下一个模式成功匹配为止

但是如果想在过几行之后再用$1是非常不好的习惯,如果调试人员在这之间又加了模式匹配,就发生了错误。

1.6.2.自动匹配变量

if (“Hello there, neighbor”=~ //S(/w+),/){

pirnt “That was ($`)($&)($’)”;

}

变量$1 中的值为there,而$&为整个被匹配的部分,注意不再是限于括号了。匹配部分的前一部分存放在$`之中,后一部分被存到$',所以输出的消息为(Hello)( there,)( neighbor)

 

这里的代价是,如果你使用了这三个自动匹配变量中的任意一个,无论在程序的什么地方,其它地方的正则表达式的运行数度会变慢一些。虽然,变慢的程度不大,但已经足够让人担忧,因此许多Perl 程序员从不使用这些自动匹配变量。相反的,使用的替代的方法。例如,如果需要使用$&,那么在整个模式上加上括号,并使用$1 代替。

1.7      一般的数量词

模式/a{5,15}/将匹配个到15 中的任意一个(包括5,和15

/(fred){3,}/将在一行中有个或者更多个fred 时匹配上(fred之间不允许有其它字符,包括空格)

//w{8}/将严格的匹配word(字母,数字,下划线)(可能被其中一个长字符串部分所匹配上)

1.8      优先级

1.在此优先级表的最顶端是括号:(()),在分组和引用内存值的时候使用。括号内部的任何部分比括号外的部分结合更紧密。

2.第二级是数量词。这里有星号(*), 加号(+),问号(?)以及由花括号表示的数量词,如{5,15}{3, }{5}等。它们通常和前一项元素结合。

3.第三级的是锚定和序列(sequence)。锚定包括(^表明字符串的开头,($)表明结尾,(/b)词界符,(/B)非词界符。序列(一个元素紧接着一个元素)实际上是一种操作,虽然它没有使用元字符。这段话的含义是一个单词中的字母结合更紧密,就像锚定紧贴字母一样。

4.优先级最低的是竖线(|),表示或。由于其优先级最低,它通常将模式划分成几个部分。它在优先级最底端是因为我们希望像|/fred|barney/里面的字母比或(|)结合更紧密。如果或(|)的优先级比序列的优先级更高,那么,上述模式的含义是匹配fre,接着是或者b然后是arney。因此,或(|)的优先级最低,字母序列的优先级要高些。

1.8.1.优先级练习

例如,/^fred|barney$/很可能并不是程序员想要的模式。由于竖线(|)的优先级最低;它将上述模式分成了两部分。这个模式在或者开头是fred,或者结尾是barney 时匹配上。很可能程序员想要的是(^(fred|barney)$),这将匹配只有fred 或者只有barney的行◆。那/(wilma|pebbles?)/呢?问号也对前面的元素有效◆,它将匹配wilmapebbles或者pebble,可能是某个长字符串的一部分(因为没有锚定)。

◆当然,结尾处可以有换行符,我们在早期讨论$锚定时提到过。

◆因为数量词?和字母结合更紧密

1.9      模式测试程序

#! /usr/bin/perl

while(<>){ #一次取一行输入

chomp;

if(/YOUR_PARTTEN_GOES_HERE/){

print “Matched: |$`<$&>$’|/n”; #特殊的变量

}else{

print “no match: |$_|/n”;

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值