- 正则表达式 是Perl最著名的特性,在Perl中使用正则表达式的简易方式是将要匹配的文本保存在
$_
中,然后用一对斜线//
将模式包起来
demo7-1
#!/usr/bin/perl
$_ = "a string for regular match";
$match_result = /regular/;
print "match result is $match_result\n";
正则表达式/regular/
返回布尔值1
:
./demo7-1
match result is 1
模式中可以使用反斜线转义字符:
\t
表示一个制表符,\b
表示一个空格,反斜线\
自己属于元字符,另一个元字符是小数点.
可以匹配除换行符以外的任意字符。若要匹配元字符,需要用反斜线转义量词用来限定匹配的次数
-
{n}
:匹配n次(= n) -
\
:匹配零次(不匹配)或匹配任意次(>= 0) -
+
: 匹配一次或一次以上 (>= 1) -
?
: 匹配零次(不匹配)或匹配一次 (= 0 || 1)
demo7-2
:
#!/usr/bin/perl
$_ = "abccba";
if(/c{2}/){
print "c{2} : matched\n";
}
if(/c*/){
print "c* : matched\n";
}
if(/c+/){
print "c+ : matched\n";
}
./demo7-2
c{2} : matched
c* : matched
c+ : matched
量词默认约束紧贴在量词左侧的模式匹配结果,如果没有使用括号进行分组,那就是一个字符,如果有分组则是整个分组的匹配结果
demo7-3
:
#!/usr/bin/perl
$_ = "abcabc";
if(/abc{2}/){
print "abc{2} matched\n";
}
if(/(abc){2}/){
print "(abc){2} matched\n";
}
./demo7-3
(abc){2} matched
abc{2}
期待匹配的是字符串abcc
-
分组用
()
将模式中的若干字符和其他字符区分开来,除了可以用来修改量词的约束范围,还可以实现反向引用,反向引用用反斜线和数字来代表对应的分组,如果有嵌套的分组,则根据左括号的先后位置排序
左右括号也是元字符,如果要匹配左右括号,需要使用反斜线转义
反向引用可以很方便的匹配重复的模式
demo7-4
#!/usr/bin/perl
$_ = "abab baba abab";
if(/(((.)(.))\3\4) \4\2\3 \1/){
print "matched\n";
}
./demo7-4
matched
\1
对应匹配的是abab
\2
对应匹配的是ab
\3
对应匹配的是a
\4
对应匹配的是b
和左括号的顺序一一对应
使用反斜线和数字组合的反向引用有可能会引发二义性问题:对于\111
,是匹配\1
和11
,\11
和1
还是\111
? Perl的做法是最大尝试,也就是匹配\111
。如果想要匹配\1
和11
就必须使用另一种反向引用的方式\g{n}
,n
代表序号,匹配\1
和11
的模式就写成\g{1}11
,用这种方式甚至可以使用负数,表示相对当前位置的反向引用。同样匹配abab baba abab
:
demo7-5
:
#!/usr/bin/perl
$_ = "abab baba abab";
if(/(((.)(.))\g{-2}\g{-1}) \g{-1}\g{-3}\g{-2} \g{-4}/){
print "matched\n";
}
./demo7-5
matched
正数的计数规则是从最左端开始向右数左括号的序数,负数则是从当前位置开始向左数左括号的序数
-
字符集用
[]
框起若干字符组成集合,模式可以匹配集合内任一字符若干次(取决于量词),集合可以是字母数字和符号,甚至是元字符(需要反斜线转义)。
demo7-6
:
#!/usr/bin/perl
$_ = "1q2w3e4r /*";
if(/[1234qwer]+ [\/\*]{2}/){
print "matched\n";
}
./demo7-6
matched
在ASCII码表中连续的字符可以用短横杠-
缩略,上面的模式中[1234]
可以缩略成[1-4]
,但是[qwer]
则不能缩略,因为这四个字符在ASCII码表中并不连续。进一步地,可以用\d
代替[0-9]
,用\w
代替所有[a-zA-Z0-9_]
。
用小写字母替代了若干字符,对应的大写字母则是他们的逆:\D
表示所有非数字0至9的字符,\W
则表示所有[^a-zA-Z0-9_]
,在字符集开始位置的^
表示的也是取反的含义。(也就是说[\w\W]
和[\d\D]
表示全集,可以匹配任何字符,甚至比通配符.
更强,因为通配符.
不能匹配换行符,但是[\w\W]
可以)
demo7-7
:
#!/usr/bin/perl
$_ = "a23\n32a";
if(/\w(\d)(\d)[\d\D]\g{2}\g{-2}a/){
print "matched\n";
}
./demo7-7
matched