perl编程:正则匹配
Posted 螺旋儿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了perl编程:正则匹配相关的知识,希望对你有一定的参考价值。
perl 是生信常用的编程语言之一,最大的亮点是正则匹配和哈希。
正则匹配是per编程中非常强大的一项应用,简单的一行代码,就可以实现对字符串的灵活处理。
本文结合日常的工作学习,介绍下正则匹配在perl中的常见使用技巧。
基本规则
正则匹配,是一种常见处理字符串的方法,在大部分编程语言中都有,并且规则大同小异。
基本格式
正则匹配有三种基本格式,如下:
匹配: m// ,通常简写为// ;
替换: s/// ;
转换: tr/// 。
替换和转换首先对前一个// 中的内容进行匹配定位,然后用后面一个//中的内容进行替换或者转换。
通配符
. 可以匹配任何单个字符,但不可以是换行符“/n” ;
* 表示匹配前面一个字符或者字符串的n倍,n可以为0,1,2...;
?表示匹配前面字符串0次或者一次;
+ 表示匹配前面字符串一次及以上。
可见 * , ? 和 + 不能独立使用,前面需要有字符串,字符串可以是由一个及以上的字符组成。
锚定符
^ 或 \A ,匹配串首,出现在匹配开头;
$ 或 \Z ,匹配串尾,出现在匹配结尾。
转义字符
\d 匹配任意数字,同[0-9]
\D 匹配除数字外的任意字符,同[^0-9]
\w 匹配任意单词字符,同[_0-9a-zA-Z]
\W 匹配任意非单词字符,同[^_0-9a-zA-Z]
\s 匹配空白,同[ \r\t\n\f]
\S 匹配非空白,同[^ \r\t\n\f]
应用实例
下面结合工作学习中最常用的一些操作,来介绍下perl 中正则匹配的应用。
应用1,分割字符串。
分割字符串生成数组是正则最常见的应用。在下面的代码中,首先将默认变量$_,也就是"aa bb cc dd ee"以空格为分割符进行分割,并生成数组,然后将第2个和第4个元素分别赋值给变量$str1和$str2。
$_ = "aa bb cc dd ee" ;
my ($str1, $str2) = (split /\s+/,$_)[1,3] ;
print "$str1\t$str2\n" ;
bb dd
下面的例子中,将变量$str中的每个字符进行切割并赋值给数组@arr,数组中的每一个元素是一个字符。
my $str = "a123bc" ;
my @arr = (split //,$str) ;
print “@arr\n” ;
a 1 2 3 b c
应用2,特殊行的处理。
在读取处理文件时,通常会跳过一些空行或者有特殊字符(例如#)的行。下面的例子中在读取文件时,去掉了只有空格的行和以“#” 开头的行,然后输出其余的行。
open IN,$infile || die $! ;
while (<IN>) {
next if (/^\s+$/) ;
next if (/^#/) ;
print $_ ;
}
close IN;
应用3,统计字符出现的次数。
统计一个字符串中特定字符或字符串的出现次数有多种方法,下面是与正则有关的几种方法。
1) tr///,转换,只能用于统计单个字符出现的次数。转换多个字符时,会返回转换的次数,而不是某个特定字符(串)的出现次数。
下面例子$n1统计了字符串 “aabbccbbaa” 中 “a” 出现的次数,而$n2统计了字符串中 “a” 或者 “b” 出现的次数,而不是 “ab” 出现的次数。
my $ss = "aabbccbbaa" ;
my $n1 = $ss =~ tr/a/a/;
my $n2 = $ss =~ tr/ab/ab/ ;
print "$n1\t$n2\n" ;
4 8
2)s///g , 全局替换,可以用替换相同字符串的方法来统计特殊字符的出现次数。
下面的例子中,$n1和$n2分别统计了字符串$ss中“a” 和“ab”出现的次数。
my $n1 = $ss =~ s/a/a/g ;
my $n2 = $ss =~ s/ab/ab/g ;
print "a:$n1\tab:$n2\n" ;
a:4 ab:1
3)匹配并累加,首先全局匹配,然后累加匹配次数,下面两种表达的效果是一样的,第二种方法更简洁一点。
my ($tmp,$cc) = (0,0) ;
if( $tmp = () = ($ss =~ /a/g ) ) {
$cc += $tmp;
}
print "a: $cc\n" ;
a: 4
my $n = 0 ;
$n += ( () = $ss =~ /a/g );
print "a:$n\n";
a: 4
应用4,字符串替换。
字符串全局替换也是常见的应用,在下面的例子中,首先将字符串“a bc de”中的空格替换为下划线,另外的操作是将空格进行了删除。没错,s/// 不仅可以做匹配替换,还可以做匹配删除。
my ($ss1,$ss2) = ("a bc de") x 2 ;
$ss1 =~ s/\s+/_/g ;
$ss2 =~ s/\s+//g ;
print "$ss1\t$ss2\n" ;
a_bc_de abcde
应用5,抓取字符串。
抓取字符这一功能非常强大,可以变着花样写正则匹配,输出你想要的结果。下面的例子是抓取了变量$str中前三个连续的字母组合,同是匹配连续的字母,用了三种表达方式,好玩吧。
my $str = "ab12cd34ef56" ;
my ($s1,$s2,$s3) = $str =~ /^([^\d]+)\d+([a-z]+)\d+(\D+)\d+/ ;
print "$s1\t$s2\t$s3\n" ;
ab cd ef
应用6,用于编写流程脚本。
在分析数据时,通常要分步骤处理,所以需要设定$Step 选项,如下代码。注意在这里每一步骤都需要判断是否执行,所以需要连续用if,而不是用elsif 或者 else。另外,需要处理的步骤数目最好不要超过10,否则会出现一些不预期的运行结果。例如,如果设定$Step = 13,则会运行Step 1,Step 3 和Step 13.
if ($Step =~ /1/) {
print STDERR "Step 1 is running...\n";
# scripts for Step 1
}
if ($Step =~ /2/) {
print STDERR "Step 2 is running...\n";
# scripts for Step 2
}
总之,正则匹配是perl的一大神器,功能强大,应用广泛。灵活使用正则匹配,你会发现原来perl也能做这么多事情,并且只用几行代码就可以搞定。快去玩吧~
PS: 封面代码 ☟ 欲知详情请测试。
my $today = "\\/\_\\/" ;
print "Today is a $today day!\n\n" ;
$today =~ s/\\\//\/\\/g ;
print "Today is a $today day!\n" ;
__ End __
☺ ☺☺ ☺ ☺ ☺ ☺☺☺ ☺
以上是关于perl编程:正则匹配的主要内容,如果未能解决你的问题,请参考以下文章