需要注意在perl中默认的模式匹配操作对象是$_;
1. 用m//进行匹配
前面提到的 / /是m//匹配符的简写,但m//与m!!,m@@,m##都表示一样的含义,即//只是圈定界限的符号而已。
2. 模式匹配修饰符
a. 用 '/i' 进行大小写无关的匹配
(m//i)斜线圈定的字符不区分大小写;
b. 用 '/s' 匹配任意字符
重要的是它可以匹配换行符;
m/ fred.*aaa/;两者间有\n则不匹配;
m/ fred.*aaa/s;两者间有\n一样匹配;
c. 用/x加入空白符
他可以使匹配符可以加入任意的空白符
m/aaa.sdsd$sss*/;
m/aaa . sdsd $ sss*/x;两者表达一样的意义
同时不同的修饰词是可以组合应用的。
d. 选择一种字符解释方式(针对5.014)
这里是指采用/a , /u , /l 选择按ascii,unicode,local来解释模式匹配。
3.锚位
用来指定匹配的位置,而无需总是从头开始。
\A:表示字符串必须以其后的字符开始;
m{\Ahttp?://}i;必须以https开头;
\z :表示字符串必须以他前面的内容结尾,后面不能有任何东西;
\Z:表示字符串必须以他前面的内容结尾,后面允许有换行符;
ex:
m{\A\s*\Z}; 表示一个空白行;
4. 单词锚位(\b)
用来查找某个词(他可以由数字,字母和下划线组成)
m{\bword\b}: - 可以匹配word,但不能匹配aword,worda。
m{\bword}; - 可以匹配wordlllll,但不匹配aword;
m{word\b} - 可以匹配aword,但不能匹配worda
\B可以匹配所有\b不能匹配的位置。
5. 绑定操作符 =~
解脱了$_;他是采用右边的模式来匹配左边的字符串。
优先级很高,其次返回值为真或者假(0或者1);
6. 模式的内插
可以进行双引号形式的内插;
ex.
#!/usr/bin/perl -w
my $what = "larry";
while (<>){
if(m{\A$what}) {
print "find it";
}
}
其中,$what并不一定需要直接声明,也可以从@ARGV中获得:
my $what = shift @ARGV; #取出第一个元素;
7. 捕获变量
很容易理解,对应了匹配模式里面小括号内的内容,只不过将这些内容放在了$1,$2,$3....里面了,可以被提出来应用。
8. 捕获变量的存活期
捕获变量会在下一次成功捕获的时候被覆盖,但是失败的捕获并不是对其有什么影响。
所以匹配模式一般总存在于if 和while语句的条件,用来判断捕获是否成功。在写perl时候,必须将捕获用if while进行判断,以防止错误。
9.不捕获变量
有时并不是所有带括号的模式匹配都是我们关心的,那么很好,我们采用了一种方法不捕获它。
/(?:kkk)(aaa)(ccz)(wqqe)/
通过在括号内加 ?: 的方式,可以不捕获它,$1捕获的是(aaa)的内容。
10.命名捕获
由于在捕获过程中可以会因为括号过多引起争议,所以引入了命名捕获;
用法:
/(?<name>匹配1)(匹配2)(匹配3)(?<name1>匹配4)/
将只捕获匹配1,4的内容,并将name,name1作为键,将捕获内容作为值存在默认的哈希 %+ 中,当需要引用时,采用 $+{name},$+{name1}引用
11. 自动捕获变量
$&:表示匹配中的数据;
$`:匹配段之前的数据;
$':匹配段之后的数据;
三者合起来就是待匹配的数据。他们的值会保存到下次模式匹配成功之前。
12. 通用量词
{n,m},表示匹配模式中出现的的次数范围;
ex:
/a{3,5}/只能匹配aaa,aaaa,aaaaa 三个。
前面说的+,?,*是这种用法的特例。
13. 优先级
1. 最高级别:(),由于分组和捕获
2. 量词
3. 锚位和序列
4. 择一竖线
5. 基础的匹配模式
有时候理解复杂的模式比较困难时,建议加上非捕获的圆括号进行分组,这样不会有捕获值。
14. 模式测试程序
在编写复杂的perl程序时,很容易搞不懂一个模式在干什么,所以需要设计一个程序,来确保是不是和自己想的一样。
#! usr/bin/perl
use 5.010;
while(<>){
chomp;
if(/your_pattern/){
print " $`<$&>$'\n";
}else{
print "no match $_";
}
}
总结
本节开始描述在使用正则表达式上一些小技巧,包含锚位,捕获变量,模式匹配修饰符等,这些小技巧或者说特别的匹配方式,在处理一些场景时,有时候是很高效,可以看看怎么使用会比较高效。