开关项
在perl语言的正则表达式中,还有一些提供额外功能的修饰字符,称为开关项。这些开关项可以成组附加在某个模式的右边界符(/)的右边,改变正则表达式的默认行为。
/g 匹配所有可能的模式,即对所有可能符号表述的字符串进行匹配(也就是忽略自左向右匹配第一个子串的原则)
/i 忽略大小写的匹配
/s 匹配任意字符(包括换行符)
/x 或略模式中的空白,目的是使其更具可读性
“/g”开关
在perl语言的模式中,默认匹配原则是从左到右,最长匹配。即如果一个字符串中含有多个符号表述的子串,根据匹配原则也仅对字符串进行从左到右扫描,做最大长度的一次匹配。模式/a*b/,字符串"aaababaaaaaaaab",匹配结果为"aaab"。
使用"/g"开关,改变模式匹配的默认行为
#程序功能:在$line中找出含有连续任意个"a"并以"b"结束的子串。
$line="aaababaaaaaaaab";
@array=$line=~/a*b/g;
foreach (@array){
print $_."\t\t";
}
“/i”开关
如果需要进行忽略大小写的匹配,则在模式的右边界符的右边附加"/i"开关,就可以进行忽略大小写的匹配。
#程序功能:判断$line中是否存在"hello"(不分大小写)
$line="Hello,world";
$line=~/hello/i;
print "$&";
当"/g"和"/i“开关一起使用
#程序功能:找出$line中忽略大小写的含有连续任意个"a"并以"b"结束的子串
$line="aaabAbaAAaaaaab";
@array=$line=~/a*b/gi;
foreach (@array){
print $_."\t\t";
}
“/s”开关
因为点号(.)在默认情况下无法匹配换行符,而有时候却需要匹配多行,那么可以在模式的右边界符的右边附加"/s“开关,这样就可以将多行视为单行进行匹配,即换行符也可匹配。
#程序功能:在含有换行符的$line中,找出以"h"开头以"d"结尾,中间含有任意字符的子串
$line="hello\nworld";
$line=~/h.*d/s;
print $&;
“/x”开关
当正则表达式很长的时候,可以在每一种模式匹配后加上空格并且在右边界符的右边附加“/x”开关,模式含义不变且更具可读性。例如,模式/\d+ \s* \w [a-zA-Z]/x等价于模式
/\d+\s*\w[a-zA-Z]/
字符串的替换操作
perl语言的正则表达式中主要的替换操作有两种
$str=~s/模式/替换串/ 将$str中符合“模式”的子串替换成“替换串”
#str=~tr/子串1/子串2/ 在$str中把每个出现在“子串1”中的字符串替换成“子串2”中对应位置的字符
“s///”方式
利用“s/模式/字符串/”方式可以实现将原子符串中匹配了模式的子串替换为该方式中指定的替换串,也就是说实现了字符串的替换操作。
注意,此替换方式中的“模式”部分可以是之前讲述的特殊含义符号,但是“替换串”部分则不能是那些符号,因为这一部分不是模式,而是要替换的字符串。
$line="I Love You 9";
#将$line中A-I中的字符串替换为[a-i]
$line=~s/[A-I]/[a-i]/;
print $line."\n";
$line="I love you 9";
#将$line中第1个最长的字母字符串替换为字符串"what a"
$line=~s/[A-I]*/what a/;
print $line."\n";
“s///”方式中,允许替换内容为空,即语句"s/模式//"是合法的。此时,用空串替换匹配了模式的第1个字符串,也就是说,实现了删除指定字符串的操作。
"$line=~s/\s*//"表示删除$line中的第1个空白字符串。
“tr///”方式
“tr/子串1/子串2/”模式其实是翻译操作,但是也可以理解为替换操作,只是它实现的是对应替换。即所匹配的子串1中的第1个字符,替换为子串2中的对应字符,所匹配到的子串1中的第2个字符替换为子串2中的对应字符,依次类推。如果成功替换,操作结果返回1,并将替换结果赋值给原子符变量。
#程序功能:将字符串中的小写字母替换成大写字母
$line="Goals are meant to be achieved.";
if($line=~tr/a-z/A-Z/){
print $line."\n";
}
“tr///”方式采用的是通过两个指定字符集(翻译集合被翻译集)实现逐个替换(对照翻译)的工作机制。
如果翻译集和被翻译集字符个数不等
#程序功能:将字符串中的小写字母替换成大写字母
$line="Goals are meant to be achieved.";
#翻译集的字符个数>被翻译集的字符个数
if($line=~tr/a-z/A-N/){
print $line."\n";
}
#程序功能:将字符串中的小写字母替换成大写字母
$line="Goals are meant to be achieved.";
#翻译集的字符个数<被翻译集的字符个数
if($line=~tr/a-n/A-Z/){
print $line."\n";
}
“tr///”与“s///”都可以实现字符串的替换操作,但在具体操作上确是不同的。“s///”方式中仅查找(匹配)部分支持特殊含义符号,替换部分并不能识别特殊含义符号。“tr///”方式中,查找与翻译部分均可以识别特殊含义符号,且如果查找成功,即可根据翻译集进行相应字符的逐个替换。
#程序功能:将字符串中的大写字母替换成小写字母
#采用"tr///"方式
$line="GOALS Are Meant To Be Achieved.";
if($line=~tr/[A-Z]*/[a-z]/){
print $line."\n";
}
#采用"s///"方式
$line="GOALS Are Meant To Be Achieved.";
if($line=~s/[A-Z]*/[a-z]/){
print $line."\n";
}