目录
perl具有强大的文本处理能力,很大一部分原因在于它有博采众长的正则表达的功能。在perl5及其以后的版本种,perl形成了完备的正则表达式功能。
正则表达式
含义
正则表达式英文叫(regular expression),其实就是一种规则(regular)的表达式。说通俗点就是用一种含有特定规则的式子来表示一群式子。比如说有10个小孩,其中有3个小孩带着红帽子,那么我就规定一种表达式,这个表达式叫“带着红帽子的”。那么“带着红帽子”就是我指定的规则。符合我这个规则的孩子将被匹配上,其他孩子则不被匹配上。这就是所谓“正则表达式”的含义。
操作符
常用的操作符如下:
=~ :进行匹配,左侧是待匹配的字符串,右侧是要匹配的模式或者说“你指定的规则”。该规则是用一对斜杠‘/’来包围的。
$string =~ /AB/
$string =~ m/AB/
上例的含义是,匹配所有含有“AB”的字符串。匹配成功则返回真,否则返回假。
上例的两行含义相同,"m"是指匹配“match”,可以被省略。
元字符
在匹配的时候,有12个字符,会被当成特定含义进行匹配。
星号‘*’ :表示其左侧的字符(或字符组)可以有任意数量,零个或任意多个。
加号‘+’:表示其左侧的字符(或字符组)可以有一个或任意多个。
问号‘?’:表示其左侧的字符(或字符组)的一个或零个。
花括号‘{}’:表示其左侧的字符(或字符组)的数量闭区间。其间可以有两个数字,由逗号隔开,左边小,右边大。如果只有单侧的数字和逗号,省略的数字表示“n”。如果只有1个数字没有逗号,则表示确切的数量。
圆括号‘()’:表示其中间的字符作为一个整体。
方括号‘[]’:表示其间的一个或多个字符作为一个可选的字符组,匹配其中任意一个字符即可。如果[]内的第一个字符是^,那么它表示除了^后面的字符的所有字符。
竖线‘|’:表示其左右两边的匹配其中一个即可。
反斜杠‘\’:放在元字符前门,撤销此元字符的特殊功能。也可以放在某些普通字符的前门组成其他含义。
句点‘.’:匹配任意一个字符。
尖角‘^’:匹配字符串的行开头。
美元‘$’:匹配字符串的行结尾。
修饰符
在模式匹配的尾部加入一些特定的字符可以给匹配规定一些附加的规则。
i:取消大小写。
s:使句点(.)符号匹配换行符(\n)。
x:忽略模式中的空格。
示例:
~/abc/s #不仅可以匹配到abc 还可以匹配到 ABC
常用的反斜杠模式和含义
\d:数字的集合。等价于[0-9]。
\n:换行符。
\s:空格字符。
\t:水平制表符tab。
\w:数字、字母和下划线的集合。等价于[_0-9a-zA-Z]。
替换
除了匹配之外,还可以对特定的内容进行替换具体语法如下:
$a =~ s/匹配内容/替换内容/
替换是把第二个/左侧匹配的所有内容,都替换为第二个/右侧的内容。匹配的方法和上文所有的匹配规则都适用。
替换同匹配一样有修饰符,添加修饰符的位置在第三个/的后面。比较常用的是/g,表示全部替换,示例:
$a = "abcde abcde"
$a =~ s/bcd/BCD/; # a会被替换为 aBCDe abcde 只替换一次
$a =~ s/bcd/BCD/g; # a会被替换为 aBCDe aBCDe 全部替换
此前介绍的修饰符也都是可以结合使用的。
示例小实验
实验一
建立一个模式,无论$what的值是什么,它都可以匹配3个$what的内容连在一起的字符串。
代码如下:
文件名:match_test.pl
#! user/bin/perl
use strict;
my $what="abc";
my @arr;
open (DATA , "<matchcase.txt") or die "can't open file.txt ";
@arr = <DATA>;
foreach(@arr){
if ($_ =~/($what){3}/){
print "match success!";
}
else{
print "miss match !";
}
}
close DATA;
读取的文件(matchcase.txt)内容如下:
总共5行数据,其中第一行含有1个“abc”,第四行含有连续3个“abc”。运行结果如下:
以上代码使用了花括号{}的方法,进行了内容的连续3次匹配,还应用了匹配时的内插变量($what),匹配的变量,而不是直接匹配文本"abc"。
实验二
写一个程序来复制并修改指定的文本文件。在副本里,此程序会把出现的字符串“abc”的每一处都改为“fff”。输入文件名应在命令行上指定,输出文件名则是本来的文件名加上“_out”。
代码如下:
代码名:replace_test.pl
#! user/bin/perl
use strict;
use Getopt::Long qw(:config bundling no_ignore_case);
my $what="abc";
my @arr;
my $in_name="";
GetOptions(
"in_name=s"=> \$in_name
)or die("Error in command line arguments\n");
print "$in_name";
open (DATA , "<$in_name.txt") or die "can't open file.txt ";
@arr = <DATA>;
foreach(@arr){
$_ =~ s/$what/fff/g;
}
close DATA;
$in_name=$in_name."_out";
open (OUT ,">$in_name.txt") or die "writing failed!";
print OUT @arr;
close OUT;
读取的文件与上文一致
输出的结果如下:
命令行输入:
以上命令行添加了一个选项为输入的文件(matchcase)。文件中所有‘abc’自动替换为‘fff’。