本章介绍如何在Perl中使用正则表达式,介绍了“查找”(m//)、“替换”(s///)及split操作符、join函数的用法。
1.使用m//进行匹配
前面两章介绍的模式,都是在一对斜杠中的,如/fred/。但这实际上是m//(模式匹配)操作符的一个快捷方式,只所以说是快捷方式是因为可以选择任何定界符对把内容括住,而当选择了斜杠作为定界符时,就可以省略开始的m。譬如,m#fred#和/fred/是等价的。
有几个选项修饰符字母,也可称为标志符(flag),可以把它们附加在正则表达式的结束定界符后面,以改变表达式的缺省行为。
/i:进行不区分大小写的匹配,如/fred/i;
/s:使点号(.)可以进行任何字符的匹配,点号原先不能匹配换行符,加上这个标志符后,就可以匹配任何字符,如/fred.*lee/s;
可以组合使用标志符,组合的顺序不重要,譬如/fred/is和/fred/si是等价的。
2.绑定操作符=~
与$_匹配只是个缺省操作。绑定操作符(binding operator)=~告诉Perl用右侧的模式匹配左侧的字符串,而不是匹配$_。譬如:
if ($some_other =~ /brub/) {
...
}
3.在模式中替换
这里的替换指的是双引号替换,即在正则表达式中,可以把变量替换为它实际的值。进行变量替换时,需要将变量放在小括号中。譬如:
my $what = "larry";
if (/^($what)/) {
...
}
4.匹配变量和记忆的持久性
在正则表达式中使用\n对匹配的字符串进行反向引用,而在Perl中,使用$n来引用匹配的字符串。两者的区别是,\n回指当前正在进行匹配的正则表达式的第n个记忆,$n表示一个已经完成的模式匹配的第n个记忆。两者有个时间差,即在同一时刻指的并不是同一个字符串。譬如:
$_ = "Hello there, neighbor";
if (/\s(\w+),/) { # 记住空格和逗号之间的单词
print "the word was $1\n"; # $1 = Hello there
}
匹配变量一般保留到下一次模式匹配成功,即一个不成功的匹配会维持以前记忆的原状,但一个成功的匹配则全部重新设置它们。这是模式匹配一般总是在if或while的条件表达式中的一个原因。由于记忆不会永远保持,所以一般在模式匹配的后面马上使用这个记忆的变量,或者将这个记忆的变量拷贝到一个普通变量中,以便后面继续使用。譬如:
if ($wilma =~ /(\w+)/) {
my $wilma_word = $1;
...
}
在Perl中,有三个系统定义的模式匹配变量,即你无须自己定义这些变量即可使用它们:
$`:保存正则表达式引擎在找到匹配之前需要跳过的部分;
$&:保存实际与模式匹配的那部分字符串;
$':保存模式没有到达的字符串的剩余部分;
将这三个字符串按顺序连在一起,你总会得到原字符串:$`$&$'。
5.用s///进行替换
使用s///可以用一个替换字符串来替换一个变量匹配模式的部分,譬如:
$_ = "He's out bowling with Barney tonight.";
s/Barney/Fred/; # 用Fred替换Barney
s///有一个返回值,如果替换成功,则返回真;否则,返回假。
和m//类似,s///可以使用绑定操作符=~ 改变匹配的变量,譬如:
$file_name =~ s/Barney/Fred/; #在$file_name中查找Barney并将其替换为Fred
和m//类似,s///也可以使用不同的定界符,此处不再赘述。
和m//类似,s///使用一组标志符来改变缺省行为:
/g:进行全局替换,如果没有这个标志,则s///仅替换匹配的第一个模式;
/i,/s:用法和m//中的类似,此处不再赘述;
6.大小写转换
在替换的时候,可能经常希望替换字符采用了合适的大写(或小写,依需要而定)。这很容易用Perl来完成,即通过一些反斜杠转义。
\U转义符强制后面的字符都用大写,譬如:
$_ = "I saw Barney with Fred";
s/(fredbarney)/\U$1/gi; #$_现在是"I saw BARNEY with FRED."
\L转义符强制后面的字符都用小写;
缺省情况下,U和L会影响其后的所有(替换)字符串,除非使用\E关闭大小写转换,譬如:
$_ = "I saw Barney with Fred";
s/(\w+) with (\w+)/\U$2\E with $1/i; # $_现在是"I saw FRED with Barney."
当写成小写的形式时(\l和\u),它们只影响下一个字符,譬如:
$_ = "I saw barney with fred";
s/(fredbarney)/\u$1/gi; # $_现在是"I saw Barney with fred."
\u\L(或\L\u)表示全部小写,但是第一个字符大写;
7.split操作符
split操作符把一个字符串按照分割子(separator)分开。格式如下:
@result = split /separator/, $string;
split操作符在字符串中用模式/separator/扫一遍,返回一个由分割子分割的字段(子字符串)的列表。每当模式匹配时,就是一个字段的结束和下一个字段的开始,因此,任何可以匹配模式的东西都不会出现在返回的字段中。譬如:
@result = split /:/, "abc:def:g:h"; # @result = ("abc", "def", "g","h")
8.join函数
join函数完成split操作符相反的功能:split把一个字符串分成若干片段,而join则把一组片段粘合起来形成一个字符串。格式如下:
my $result = join $glue, @pieces;
join的第一个参数是粘合串,它可以是任何字符串。另一个参数是由片段组成的一个列表,join把粘合字符串放在片段之间。譬如:
my $x = join ":", 4,6,8,10,12; # $x = "4:6:8:10:12"