perl 的核心,也是最重要的一点就是正则表达式了,也叫做模式,是一个匹配字符串的模板。有了它,可以更好地处理文本。
1)简易模式。 的使用简单正则表达式,其实就是对字符串进行匹配。比如这样:
while (<>) {
chomp;
if (/pattern/) {
print "matched!";
}
}
此时perl会将读入的一行存进$_,然后对其进行'/ /' 中的模式进行匹配,如果是/love/,就是检查输入中有没有出现‘love’。
如果只能匹配这样的字符串,那就太没意思了,所以,perl中有一些特殊的通配符,常用的有'.' ,可以匹配任何一个字符(除了换行\n),在搭配上一些量词,功能就很强大了,比如‘*’(前面的内容出现0-n次) '+' (出现1-n次) '?'(出现0或者1次) ‘{n}’(直接指定出现n次)。最常用的比如 .* 表示任意字符任意次(除了换行\n)。
可以在匹配中加入括号表示分组,/(love)+/,意思应该一目了然,代表love出现1-n次,特殊作用就是反向引用,像这样/(.)(.)\2\1/ 可以表示abba这样的字符,数字代表与相应括号中的字符的重复。更加安全的写法是/(.)(.)\g{2}\g{1}/。
择一匹配,/hi|hello/,使用竖线‘|’ 可以表示或,有一个匹配到就成功。
为了我们更方便的工作,perl 加入了很多字符集,以节约我们的按键,常用的比如:
[A-Za-z0-9_] => \w ,可以更好的匹配任何单词,有字母数字下划线组成。
[0-9] => \d,表示数字。
[\f\t\n\r ] => \s,表示空白。
相应的大写版本\W \D \S ,表示除他们之外的任意字符,脱字符^ 表示除什么之外的任意字符。另外,[\d\D] 会匹配任何字符(包括换行符\n).
2.更强的匹配。
下面我们将对简易模式进行增强,首先,/ / 匹配其实是m/ / 的缩写,也可以使用m# #,m& &,都是可以的。
可以使用可选修饰符对正则表达式进行修饰,放在/ /结尾的定界符的右边。
/ /i 表示大小写无关的匹配
/ ./s 将点号匹配任意字符,特别是换行符\n
/ /x 随意加入空白,目的是更好读,易于理解
当然,这三个修饰符可以进行任意组合,比如/ /six
对单词的处理,可以使用锚位。如/^hello.*hi$/表示匹配以hello开始,hi结尾的一行,其中^与$分别表示字符串的开头和结尾。
更小范围的,可以使用/\bhello\b/匹配纯正的单词hello,\B意思相反。
默认情况下匹配的是$_,绑定操作符 =~ 可以用左边的字符串来匹配。如 if ($line =~ /\bhello/),如果匹配到会返回真。
上面所讲到的正则表达式只能进行匹配,而无法对匹配的字符进行处理,想要更高级的功能可以使用捕获变量,使用()来捕获变量进行处理。
如 if ($line =~ /(hello) (hi)/) {
print "$1 $2\n";
}
其中$1 $2 分别按顺序表示在圆括号中捕获的字符串,这里分别是hello hi。
捕获到的变量不会永久存在,也就是只能在这一次捕获成功的地方使用$n,它的值会保存到直到下一次成功的捕获,如果想多次使用,可以先放进变量中,如:$val = $1。
只要加了圆括号就启动了捕获功能,如果不想让它捕获可以这样,/(?:hello)(hi)/,现在$1就表示hi。
如果加入圆括号太多可能让人眼花缭乱,可以使用命名捕捉,这样:
if ($line =~ /(?<name1>) (?<name2>)/) {
print "$+{name1} $+{name2} \n";
}
perl中有三个捕获变量不使用圆括号,它将字符分成三部分,分别是$&,$`, $',分别表示捕捉到的字符,前面部分的和后面部分的字符。
模式测试程序,检查某些字符串是否能被指定的模式匹配:
#!usr/bin/perl
while (<>) {
chomp;
if (/pattern/) {
print "Matched: |$`<$&>$'|\n";
} else {
print "No match:|$_|\n";
}
}
3.更强大的文本处理。
a).替换 while (<>) {
if ($times = ($_ =~ s/a/b/g)) {
}
}
将$_中的a替换成b,并且返回替换的次数放在$times,s///g之后的g表示全局替换。除了进行替换外还可以统计文本中字符出现的次数。
b)分割和胶水函数.
可以使用split分割函数拆开一个字符串,如:@arr = split /:/, "a:b:cd";此时@arr中存储三个元素,分别是a b cd。另外,split会保留开头的空字段,而省略结尾的空字段。如果要以空白分割,更常见的是:@arr = split; 就这样的简单。
有了分割,就有胶水函数进行联合。如:$line = join ":", a, b, cd; $line存储“a:b:cd”。