perl 模式匹配总结
正则表达式――perl模式匹配 From: http://blog.csdn.net/utopia_wang/article/details/1531285 补充:http://www.regexlab.com/zh/regref.htm Practiacl Extraction and Report Language 一.模式匹配操作符 1.tr/ / /?替换操作符不支持正则表达式?也不具备双引号替换能力 ??????m/ /??s/ / /?都支持正则表达式,并且可以提供或限制双引号替换能力(当用单引号作为操作符时则不具备变量替换能力) s/ / /,tr/ / /??可以用两组不同的括号进行分割,以保证格式清晰s(good)<bad> 2.绑定操作符?=~,!~,m/ /??s/ / /??tr/ / /?都支持 绑定操作符的优先级非常高 ? 3. perl?特有的全局变量 1.??$`,$&,$’?分别存有匹配内容左,匹配内容,匹配内容右的内容 2.?可以用()捕获特定的模式?并依次存入?$1 $2 $3?中 二.模式修饰词 m/ /??s/ / /??和?tr/ / /?的修饰词不同
my $str = "hello chinaUnix i am wlj !"; $str =~ s/(s+)/length($1) == 1 ? $1 : '_' x length($1)/eg; #$str =~ s/(s{2,})/'_'x length($1)/eg; print "$str "; ##------结果-------------------- hello_____chinaUnix i am wlj___! 三.m/ /??匹配 1.分隔符 用???或?‘?作分隔符时有特殊的含义 m???表示只匹配一次 m’ ‘?表示禁止变量替换和六种转换??? 2.返回值 标量环境里?匹配成功返回?1?,失败?返回?0 列表环境里,?返回子字串的列表,并捕获()中的模式 ??( $key,$value) =~ m/(/w+:(/.*)/ ; /g?修饰词的返回值 列表环境?:?返回所有匹配字串的列表 ?如:?my @perls = $string =~ m/perl/ig ; 如果有捕获圆括号,则返回捕获到的字串 ?如:?用字串?$string = “password=xyzzy verbose=9?score=0” 初始化下面的散列:%hash = {password => “xyzzy”,verbose => 9,socre=>0}; %hash = $string =~ /(/w+)=(/w+)/g ;?# 利用列表环境下匹配得到数组,再通???????????????????????????????????????????# 过数组对散列hash赋值 标量环境中?/g表示一次渐进的匹配,它令perl从上一次匹配停下来的位置开始一次新的匹配如:?while (/perl/g) { print “ $& /n”}; # 需求举例 # 求出0- 300 中出现过多少次数字9 # use strict; my $num = 0; foreach (0..300) { $num += $_ =~ s/9//g; } print "$num "; 三.s/ / /?操作符(替换) 返回值: 标量环境里返回值是成功替换的次数 替换部分被当作双引号看待可进行变量转换,而且可以使用前半部分模式匹配得到的变量$1,$2,$3 $&,等 新的修饰词 /e?把右边当作一个表达式计算 利用s/ / /?修改字串的用法 1.($newStr = $oldStr)=~ s/good/bad/g 2.替换数组的每一个元素: ???????For (@newArray,@oldArray) {s/$_/newStr/g} 3.用单程循环对同一个变量重复替换 ????For ($string) { ???????s/^/s//;??#?丢弃开头的空白 ???????s//s$//;??#?丢弃结尾的空白 ???????s//s+//g; #?丢弃中间的空白 } 4.把逗号放到整数的合理位置 $_ = “12345678”; 1 while s/(/d)(/d/d/d)(?!/d)/$1,$2/; Print “$_ /n”??#?输出:?12,345,678 四.Tr/ / /?操作符?(转换) 1.tr?不支持正则表达式?和?变量替换,只是一种单纯的划定范围的替换 ???????尽管不支持变量替换,但可以用eval expr实现 ????$count = eval “tr/$oldStr/$newStr/”; ????Die if $@; 如果仅仅是转换大小写 不要使用tr/ / /??建议使用双引号里的?转移字符?/U /L?类似的uc lc?函数 2.修饰词,与m/ /??s/ / /??的修饰词不同 /c?与searchlist?为补 /s?消除重复的字符 /d?删除找到的但没有替换的字符?,任何再searchlist?中声明但再replacement没有给出替换的字符将被删除。 如果没有/d?修饰词,那么 1),replacement?比?searchlist?短,则将复制replacement最后一个字符直到足够长 2),replacement?为空,则?replacement = searchlist?可以用此用法统计次数和/s?压缩 ?????????????????????$string =~ tr/a-zA-Z//s??# bookkeeper -> bokeper 五.元字符 12个元字符?/??|??(??)??[??{??^??$??*??+??? ^?:?在字符集中?^?表示补集?[^1,2,3]?除了1,3 ????????在一般的模式中表示?以什么开头 $?:?表示以什么结尾 六.量词??分为最大量词,最小量词(由?控制) 1.最大量词 *??匹配0?或更多次 +?匹配1?或更多次 ??匹配?1?或?0?次 {count}匹配count次 {min,}?匹配至少min次 {min,max}?匹配至少?min次,但不超过max次 2.最小量词 *??匹配0次或更多次 +?匹配1次或更多次 ??匹配0次或1次 ??匹配最多min次 {min,max}??匹配至少min次,但不超过max次 七.常用的字母数字正则元符号 .???通配符匹配除了换行符外的任何单字符(如果加上修饰词/s?也可以匹配换行符) /d??数字?[0-9] /D??非数字 /s??空格 /S??非空格 /w??字?[a-zA-Z0-9_] /W??非字 /E??结束大小写或掩码 /l??把下一个字符变成小写?/u?大写 /L??把/E以前的字母都变成小写??/U?大写??如:s/revision//u$&/g; ?######################################################################### # #?????论坛实际问题及零散知识点 #
###########################################################################
?
1.正则匹配的特殊变量
@-? 最近一次正则表达式匹配的部分在目标字串中的起始偏移量
@+?最近一次正则表达式匹配的部分在目标字串中的终止偏移量
$&? 最近一次正则表达式匹配到的部分
$`?? 在目标字串中最近一次正则表达式匹配到的部分之前的内容
$'?? 在目标字串中最近一次正则表达式匹配到的部分之后的内容
# 正则匹配 特殊变量测试代码 # #!/usr/bin/perl use strict; use warnings; my $str = "abcedfabcertfabciruabc"; while ($str =~ /(abc)/g) { # 注意捕获匹配的小括号不能少 print "$-[1] -- $+[1] "; # 也可以是print "$-[0] -- $+[0] "; print "$` -- $& -- $' "; } # 运行结果 bash-2.03$ testString.pl 0 -- 3 -- abc -- edfabcertfabciruabc 6 -- 9 abcedf -- abc -- ertfabciruabc 13 -- 16 abcedfabcertf -- abc -- iruabc 19 -- 22 abcedfabcertfabciru -- abc -- my $str = "abcedfabcertfabciruabc"; if ($str =~ /(^abc)w+(abc)w+(abc)w+(abc$)/g) { print "$-[0] -- $+[0] "; # $-[0],$+[0] 存储的是整个正则表达式匹配的部分的起始和结束坐标 print "$-[1] -- $+[1] "; # 与小括号捕获的无关 print "$-[2] -- $+[2] "; print "$-[3] -- $+[3] "; print "$-[4] -- $+[4] "; print "$`--$&--$' "; ## $` $&,$' 存储的是正则表达式匹配到的自符。及其左右。 } ## 运行结果 bash-2.03$ testString.pl 0 -- 22 0 -- 3 6 -- 9 13 -- 16 19 -- 22 --abcedfabcertfabciruabc-- ## $` $&,$' 存储的是正则表达式匹配到的自符。及其左右。 日志分析需求代码: ############# # 切出两行对齐部分 ############# #uniqu- TCACAACATGGTATCAGAGCAGGT #TA4806 ACTCTGTTTTTCTTCTCTCTCTCAATAATCCAACATGGTATCAGAGCCGATGGTTGTCCT # # #uniqu- TCACAACATGGTATCAGAGCAGGT #TA4891 TATCTTCTTCTCCGTAACAAACTCTTCTGTAACATGGTATCAGAGCATGAATGGTGAATC use strict;use warnings; my $UrFile = "/shvpn/test/wlj/perl/substr.log"; open(FILE,"<$UrFile")||die "Can't open the file : $! "; my($slength,$swidth,$spaces); while(<FILE>){ # chomp; if (/^s*$/) { # 匹配空行 print "$_"; } elsif(/^uniqu/){ chomp; # 每行都会有回车结尾,先去除 if(/w+s*$/){ $slength=$-[0]; 获取匹配字串的起始坐标 $swidth=length($&); } $spaces=" "x$slength; # x用法 print $spaces," "; }else{ if(/^S/){ chomp; my $string=substr($_,$slength,$swidth); print $spaces,$string," "; } } } close FILE; ## 运行结果 bash-2.03$ logAnalyse.pl TCACAACATGGTATCAGAGCAGGT CAATAATCCAACATGGTATCAGAG TCACAACATGGTATCAGAGCAGGT TCTTCTGTAACATGGTATCAGAGC (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |