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编程:正则匹配的主要内容,如果未能解决你的问题,请参考以下文章

Perl编程-6正则表达式--替换+转化

Perl 正则表达式匹配大型 Unicode 代码点

python 正则表达式 re模块基础

Perl - 正则表达式匹配的输出非常奇怪,确实

perl正则表达式怎么匹配多行?

perl 正则表达式 模糊匹配