Perl正则表达式超详细教程
前⾔
想必学习perl的⼈,对基础正则表达式都已经熟悉,所以学习perl正则会很轻松。这⾥我不打算解释基础正则的内容,⽽是直接介绍基础正则中不具备的但perl⽀持的功能。关于基础正则表达式的内容,可参阅基础正则表达式。
我第⼀个要说明的是,perl如何使⽤正则。还记得当初把《精通正则表达式》的书看了⼀遍,把perl正则也学了个七七⼋⼋,但是学完后却不知道怎么去使⽤perl正则,虽然⾥⾯也介绍了⼀点如何使⽤perl语⾔,grep的"-P"选项使⽤的也是perl正则,ack⼯具⽀持的也完全是perl 正则,但都没有完整地体现perl正则的功能,总感觉缺点啥。最⼤的⽆奈莫过于此了,学了知识,却不知道怎么完整地应⽤。所以,我把如何使⽤perl正则来匹配数据放在最开头介绍,包括匹配指定字符串、匹配变量、匹配标准输⼊(如管道传递的数据)以及匹配⽂件中的每⼀⾏数据,⽽且后⽂我假设各位和我当初⼀样,完全没有perl语⾔基础,所以我会介绍⼀些perl语⾔和后⽂相关的语法,确保全⽂学习过程没有任何阻塞。
另外,本系列只介绍匹配操作,关于内容替换,因为和学习使⽤perl正则并⽆多⼤关系,所以替换相关的将在下⼀篇⽂章单独解释。
这⾥推荐⼀个学正则⾮常好的资料:stackflow上关于各种语⾔(perl/python//java/ruby等等)的正则的解释、⽰例,这⾥收集的都是对问题解释的⾮常清晰且⾮常经典的回答。在我学习perl正则的时候,对有些功能实在理解不了(想必你也⼀定会),就会从这⾥答案,⽽它,也从来没让我失望:stackoverflow/questions/22937618/reference-what-does-this-regex-
mean/22944075#22944075
以下是perl正则的man⽂档:
perl正则快速⼊门:man perlrequick
perl正则教程:man perlretut
perl正则完整⽂档:man perlre
学perl正则必备的⼀点基本语法
新建⼀个⽂件作为perl脚本⽂件,在其⾸⾏写上#!/usr/bin/perl,它表⽰⽤perl作为本⽂件的解释器。写⼊⼀些perl程序后,再赋予执⾏权限就可以执⾏了,或者直接使⽤perl命令去调⽤这个脚本⽂件,前⾯的两个过程都可以省略,这和shell脚本的⽅式是完全⼀样的,⽆⾮是将bash替换为了perl,想必各位都理解。
1.print⽤来输出信息,相当于shell中的echo命令,但需要⼿动输⼊换⾏符"\n"进⾏换⾏。
例如:
#!/usr/bin/perl
print "hello world\n"; # 注意每⼀句后⾯都使⽤分号结尾
保存后,执⾏它(假设脚本⽂件名为test.pl):
$ chmod +x test.pl
$ perl test.pl
2.变量赋值
perl中的变量可以不⽤事先声明,可以直接赋值甚⾄直接引⽤。注意变量名前⾯总是需要加上$符号,⽆论是赋值的时候还是引⽤的时候,这和其它语⾔不太⼀样。
#!/usr/bin/perl
$name="longshuai";
$age=18;
print "$name $age \n";
3.if语句⽤来判断,语法格式为:
if(condition){
body
}else{
body
}
例如:
$age = 18;
if($age <= 20){
python入门教程 非常详细 pdfprint "age less than 20\n";
} else {
print "age greate than 20\n";
}
4.默认参数变量
在perl中,对于需要参数的函数或表达式,但却没有给参数,这是将会使⽤perl的默认参数变量$_。
例如,下⾯的print本来是需要参数的,但是因为没有给参数,print将输出默认的参数变量$_,也就是输出"abcde"。
web和javaweb是什么关系$_="abcde";
print ;
perl中使⽤$_的地⽅⾮常多,后⽂还会出现,不过⽤到的时候我会解释。
5.读取标准输⼊
perl中使⽤⼀对尖括号格式的<STDIN>来读取来⾃⾮⽂件的标准输⼊,例如来⾃管道的数据,来⾃输⼊重定向的数据或者来⾃键盘的输⼊。需要注意的是,<STDIN>读取的输⼊会⾃带换⾏符,所以print输出的时候不要加上额外的换⾏符。
例如,在test.pl⽂件中写⼊如下内容:
#!/usr/bin/perl
$data=<STDIN>;
print "$data";
然后⽤管道传递⼀⾏数据给perl程序:
echo "abcdefg" | perl test.pl
只是需要注意,将<STDIN>赋值给变量时,将只能读取⼀⾏(遇到换⾏符就结束读取)。例如下⾯的perl将读取不了"hijklmn"。
echo -e "abcdefg\nhijklmn" | perl test.pl
如果想要读取多⾏标准输⼊,就不能将其赋值给变量,⽽是使⽤foreach来遍历各⾏(此处不介绍其它⽅式):
foreach $line (<STDIN>){
print "$line";
}
以上就是foreach的语法:
圆括号中的内容是待遍历对象,通常是⼀个列表,⽐如上⾯⽤<STDIN>读取的多⾏数据就是⼀个列表,每⼀⾏都是列表中的⼀个元素;
$line称为控制变量,foreach在每次迭代过程中都会选中⼀个列表中的元素赋值给$line,例如将读取的每⼀⾏都赋值给$line。
可以省略$line,这时就采⽤默认的参数变量$_,所以以下两个表达式是等价的:
foreach (<STDIN>){
print "$_";
}数据库sqrt函数用法
foreach $_ (<STDIN>){
print "$_";
}
6.读取⽂件中的数据
正则强⼤的⽤处就是处理⽂本数据,所以必须要说明perl如何读取⽂件数据来做正则匹配。
我们可以将⽂件作为perl命令⾏的参数,perl会使⽤<>去读取这些⽂件中的内容。
foreach (<>){
print "$_";
}
执⾏的时候,只要把⽂件作为perl命令或脚本⽂件的参数即可:
perl test.pl /etc/passwd
7.去掉⾏尾分隔符
由于<>和<STDIN>读取⽂件、读取标准输⼊的时候总是⾃带换⾏符,很多时候这个⾃带的换⾏符都会带来格式问题。所以,有必要在每次读取数据时将⾏尾的换⾏符去掉,使⽤chomp即可。redhat和ubuntu哪个好
例如:
foreach $line (<STDIN>) {
chomp $line;
print "$line read\n";
}
以下是执⾏结果:
[root@xuexi ~]# echo -e "malongshuai gaoxiaofang" | perl 26.plx
malongshuai gaoxiaofang read
如果上⾯的例⼦中不加上chomp,那么执⾏结果将像下⾯⼀样:
[root@xuexi perlapp]# echo -e "malongshuai gaoxiaofang" | perl 26.plx
malongshuai gaoxiaofang
read
显然,输出格式和print语句中期待的输出格式不⼀样。
前⾯说过,可以省略$line,让其使⽤默认的参数变量$_,所以可以这样读取来⾃perl命令⾏参数⽂件的数据:
foreach (<>) {
chomp;
print "$_ read\n";
}
8.命令⾏的操作模式
其实就是⼀⾏式。perl命令⾏加上"-e"选项,就能在perl命令⾏中直接写perl表达式,例如:
echo "malongshuai" | perl -e '$name=<STDIN>;print $name;'
因为perl最为⼈所知的就是它应⽤了各种符号的组合,让⼈看着怪异⽆⽐,⽽这些符号放在命令⾏中很可能会被shell先解析,所以强烈建议"-e"后表达式使⽤单引号包围,⽽不是双引号。fermi是什么意思
更建议,如果可以,不要使⽤perl命令⾏的⽅式,调试起来容易混乱。
perl如何使⽤正则进⾏匹配
使⽤=~符号表⽰要⽤右边的正则表达式对左边的数据进⾏匹配。正则表达式的书写⽅式为m//。关于m//,其中斜线可以替换为其它符号,规则如下:
双斜线可以替换为任意其它对应符号,例如对称的括号类,m(),m{},相同的标点类,m!!,m%%等等
网页设计与制作教程邓长寿只有当m模式采⽤双斜线的时候,可以省略m字母,即//等价于m//
如果正则表达式中出现了和分隔符相同的字符,可以转义表达式中的符号,但更建议换分隔符,例如/http:\/\//转换成m%%
所以要匹配内容,有以下两种⽅式:
⽅式⼀:使⽤data =~ m/reg/,可以明确指定要对data对应的内容进⾏正则匹配
⽅式⼆:直接/reg/,因为省略了参数,所以使⽤默认参数变量,它等价于$_ =~ m/reg/,也就是对$_保存的内容进⾏正则匹配
perl中匹配操作返回的是匹配成功与否,成功则返回真,匹配不成功则返回假。当然,perl提供了特殊变量允许访问匹配到的内容,甚⾄匹配内容之前的数据、匹配内容之后的数据都提供了相关变量以便访问。见下⾯的⽰例。
例如:
1.匹配给定字符串内容
$name = "hello gaoxiaofang";
if ($name =~ m/gao/){
print "matched\n";
}
或者,直接将字符串拿来匹配:
"hello gaoxiaofang" =~ m/gao/;
2.匹配来⾃管道的每⼀⾏内容,匹配成功的⾏则输出
foreach (<STDIN>){
chomp;
if (/gao/){
print "$_ was matched 'gao'\n";
}
}
上⾯使⽤了默认的参数变量$_,它表⽰foreach迭代的每⼀⾏数据;上⾯还简写的正则匹配⽅式/gao/,它等价于$_ =~ m/gao/。
以下是执⾏结果:
[root@xuexi perlapp]# echo -e "malongshuai gaoxiaofang" | perl 26.plx
malongshuai gaoxiaofang was matched 'gao'
3.匹配⽂件中每⾏数据
foreach (<>){
chomp;
if(/gao/){
print "$_ was matched 'gao'\n";
}
}
4.如果想要输出匹配到的内容,可以使⽤特殊变量$&来引⽤匹配到的内容,还可以使⽤$`引⽤匹配前⾯部分的内容,$'引⽤匹配后⾯部分的内容
例如:
aAbBcC =~ /bB/
由于匹配的内容是bB,匹配内容之前的部分是aA,匹配之后的部分是cC,于是可以看作下⾯对应关系:
(aA)(bB)(cC)
| | |
$` $& $'
以下是使⽤这三个特殊变量的⽰例:
$name="aAbBcC";
if(/bB/){
print "pre match: $` \n";
print "match: $& \n";
print "post match: $' \n";
}
需要注意的是,正则中⼀般都提供全局匹配的功能,perl中使⽤修饰符/g开启。当开启了全局匹配功能,这3个变量保存的值需要使⽤循环语句去遍历,否则将只保存第⼀次匹配的内容。例如:
$name="aAbBcCbB";
if(/bB/g){ # 匹配完第⼀个bB就结束
print "pre match: $` \n";
print "match: $& \n";
print "post match: $' \n";
}
while(/bB/g){ # 将迭代两次
print "pre match: $` \n";
print "match: $& \n";
print "post match: $' \n";
}
perl⽀持的正则
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论