分类:
2010-08-31 14:35:09
|
关于元字符:
点号(.)是任何单字符的通配符,当然换行("\n")要除外。因此,betty将会被/bet.y/这个模式匹配,而betsy、bet=y、bet.y,或是任何前三个字符为bet、中间接任何一个字符(换行符除外)、后面为y的字符串,也都会被/bet.y/匹配。
要是希望只能匹配句点号本身,只需在前面加上反斜线就好了。例如:/3\.14159/这个模式里面就没有通配符。如果要得出真正的反斜线,用两个反斜线表示。
简易的量词:
*用来匹配重复多次或零次的内容。
/fred\t*barney/能匹配fred和barney之间有任意多个制表符的串。也可以是零个制表符。
如果除了制表符外还想匹配其它字符就用(.*),它会区配任意字符无限多次。也就是说,不管fred与barney之间夹着什么东西。
都会匹配/fred.*barney/。.*经常戏称捡破烂模式。因为它能通吃所有的字符串。
星号是一种量词,+号也是一个量词。加号会匹配前一个条目一次以上。
/fred +barney/会匹配fred与barney之间用空格隔开而且只用空格隔开的字符串(空格不是元字符)。它不会匹配fredbarney。
因为加号表示两个名称之间必须有一个以上的空格。
第三个量词与星号及加号类似,但是限制更严格。也就是问号(?),表示前一个条目是可有可无的。就是说,它的前一个条目可以出现一次,或是不出现。问号指定了前一个条目出现的次数。可以更为:“刚才所说的,有还是没有都行”。
模式分组:
/(fred)+/ 会匹配像fredfredfredfred这种字符串。
/(fred)*/ 会匹配像Hello, world这样的字符串。
圆括号同时也使得部分字符串重新引用成为可能。我们可以用反向引用圆括号中(的模式所)匹配的文字。\1、\2这样的写法就是
在使用反向引用。而反斜线后面的数字和括号的组号匹配。
#!/usr/bin/perl -w
$_ = "abba";
if (/(.)\1/) { #same 'bb'
print "It matched same character next to itself!\n";
}
(.)\1表明需要匹配连续出现的两个同样的字符。(.)会首先匹配a,但是在匹配反向引用的时候就会发现下一个字符不是a,导致匹配
失败。Perl会跳过这个字符,用(.)来匹配下一个字符b,在匹配反向引用的时个会发现下一个字符也是b,这样就构成了成功的匹配。
反向引用不必总是附在相应的括号后面。下面的模式会匹配y后面的4个连续的非回车字符,并且用\1在d字符之后重复这4个字符:
|
Perl 5.10有一种新的反向引用写法。不再只是简单地用反斜线和组号,而是用了g\{N}这种写法。其中N是想要反向引用的组号。
以往在数字模式中使用反向引用,就会觉得非常麻烦。下面的例子我们要用\1来重复刚刚括号匹配的字符,然后是紧接着的原始串
11。如下:
|
通过使用\g{1}就能排除前面的模式中的二义性:
|
用\g{N}写法的额外好处是,我们甚至可以用负数,相比绝对位置的反向引用,相对反向引用会更加有趣。
|
这样若要在模式中加入更多的内容,就不必总是修改反向引用了,因为要加入另外一组括号,就会导致大多数绝对反向引用失效,面相对反向引用则不会,因为它使用的是相对于自己的位置,而不是绝对编号。
|
择一匹配:
竖线(|)通常可以读成“或”,意思是左边匹配或者右边匹配都行。也就是说如果左边的模式匹配失败了,还可以用右边的再试试。
因此/fred|barney|betty/能匹配任何含有fred或者barney或者betty的字符串。
/fred( |\t)+barney/ 匹配fred和barney之间空格、制表符或两者组合出现一次以上的字符串。加号表示重复一次或更多。每次
只要有重复,( |\t)就可能匹配空格或制表符。在这两个名字之间至少要有一个空格或制表符。
/fred( +|\t+)barney/ 中间的分隔符就是一定得全是空格或全是制表符。
/fred (and|or) barney/ == /fred and barney|fred or barney/
字符集:
字符集是指一串可能出现的字符集合,通过写在方括号([])内来表示。它只匹配单个字符,但可以是字符集里列出的任何一个。
例如:字符集[abcxyz]会匹配这7个字符中的任何一个。为了方便起见,可以用连字符(-),这样之前的字符集也可以写成[a-cw-z]。这样就非常方便。
定义字符集时可以使用字符简写,类似双引号内的转义序列。因此字符集[\000-\177]将会匹配任何7位的ASCII字符。
|
有时候指定字符集范围以外的字符会比指定字符集内的字符更易。可以在字符集内部开头的地方加上脱字符(^),表示这些字符除外。也就是说,[^def]会匹配这三个字符以外的任何字符。
[^n\-z] 匹配n、连字符与z以外的任何字符。
/HAL-[0-9]+/里的第一个连字符则不需要反斜线,因为字符集括号以外的连字符没有特殊意义。
字符集简写:
代表任意数字的字符集[0-9]可以被简写成\d。上面可以写成/HAL-\d+/。
\w表示单词字符:[A-Za-z0-9_],\w并不会匹配一个单词,它只会匹配单词字符集里的一个字符。虽然如此,只要加修饰符就行了。/fred \w+ barney/这样的模式,会匹配fred、一个空格、一个单词再接一个空格与barney。
更灵活的匹配空白:\s它相当于[\f\t\n\r]换页、制表、换行、回车这些都是专门用来移动打印位置的字符,它们不消耗墨水。
\s只会匹配字符集里的某个字符,因此,比较常见的做法是使用\s*来匹配任意数目的空白(也包括零个空白),或用\s+来匹配一个以上的空白符(事实上,不带量词使用\s是很少见的)。
Perl 5.10 增加了\h匹配横向空白,就是一个包含制表符和空格的字符集[\t ]。\v这个用来匹配纵向的空格,其实也就是一个包含[\f\n\r]的快捷方式。\R简写能匹配任何类型的断行。
[^\d] == \D
[^\w] == \W
[^\s] == \S
这些简写既可以作为模式里独立的字符集,也可以作为方括号里字符集的一部分。也就是说,/[\dA-Fa-f]+/可以用来匹配十六进制。
[\d\D]表示任何数字或非数字,也就是说,它会匹配任何字符!这是匹配任意字符(包括换行符)的常见做法。(而点则匹配换行符以外的所有字符)
|