美文网首页perl入门
perl入门07:正则表达式(基础)

perl入门07:正则表达式(基础)

作者: 小贝学生信 | 来源:发表于2020-04-19 21:54 被阅读0次

    一、常用正则表达式

    1、元字符

    • \ 反斜线:转义符;
    • . 点号:代替任何一个单字符,除了换行符以外;
    • * 星号:表示前面的字符重复0到多次;
      若前面的字符加上括号,就表示括号内字符串为整体进行模式匹配,下同。
    • + 加号:表示前面的字符重复1到多次;
    • ? 问号:表示前面的字符重复0或1次;
    • {1,8} 大括号:表示手动设定匹配重复的范围;
    • .* 点星组合:表示任意长度字符串,常用;

    2、字符集

    • (b|c|d|e|h|z)at[bcdehz]at[b-fhz]at 三者表达意义相同,择一匹配。
    • [a-z] 表示小写字母集;[A-Z] 表示大写字母集。
    • [0-9] 表示任一数字,等价于\d\d+表示任意长度数字(常用),类似的是\s+表示任意长度空白(也很常用),比如my @line=split /\s+/,$_;
    • \w 表示任一数字,字母以及下划线;即等价于[a-zA-Z0-9_]
    • ^$分别表示行首、行尾匹配;举一例便明白了^ATG.*TAA$表示匹配以ATG开头、以TAA结尾的序列。
      注意:如果脱字符^用于[ ]中,就表示取反;比如[^0-9]表示匹配一个非数字字符,等价于[^\d]\D

    这里顺带复习下vim的操作:d^表示删除光标至行开头的地方;d$表示删除光标至行结尾的地方

    二、使用正则表达式

    1、配合if,判断是否存在特定类型字符

    即用到正则表达的匹配 ,格式为m/<1>/<2>

    • m 表示匹配格式,若匹配到则为真,否则为假;可以省略。
    • / / 为界定符,也可以为其它,比如! !等;
    • <1> 即为想要匹配的模式,通常会用到第一点的知识;
    • <2> 为修饰符,即为对匹配过程的功能修饰,见下面的例子;可省略。
    1.1、最简单的例子
    #!/usr/bin/perl -w
    use strict;
    $_="hello,world!"
    if (/hello/) {   #在变量值中匹配是否有“hello”,有则为真;否则为假
        print "it is matched\n"
    } else {
        print "it is not matched\n"
    }
    

    注意如果 if ( /<1>/)条件括号内不加变量名,即表示与$_标量匹配;
    if ( $sample=~ /<1>/) 即为与某特定变量进行匹配的格式。

    1.2、匹配输出特定序列
    #!/usr/bin/perl -w
    use strict;
    
    open IN,"<$ARGV[0]",or die "can not open the file\n$!";
    while (<IN>) {
        chomp;
        if (/^ATG.*TAA$/i) {
    #匹配以ATG开头,TAA结尾的序列文件
        #if (!/^ATG.*TAA$/i) {
            #表示匹配不是以ATG开头,TAA结尾的序列文件
            print "$_\n";
        } else {
            next;
        }
    }
    close IN;
    
    perl 002.pl seq.txt
    
    筛选序列
    1.3、匹配修饰符
    #!/usr/bin/perl -w
    print "Do u like perl?\n";
    my $choice=<STDIN>;   #从标准输入获取信息
    if ($choice=~ /y e s/ix) {
    # i修饰符 表示忽略大小写
    # x修饰符 表示忽略空格
        print "Yes,So you need to work hard\n";
    } else {
        print "No,So you need to work harder\n";
    }
    

    2、捕获文本中特定类型的字符

    • ( ) 小括号加在正则表达式中,表示捕获括号内的特定类型字符赋值给变量。
    • 一般第一对括号赋值给$1变量;第二对括号赋值给$2变量....

    注意由于上文提到小括号还有整体分组的功能;为了避免此功能的矛盾,设置(?: )表示仅有整体分组功能,不捕获值。

    • 一个复杂的例子:取出"Score = 161 bits (407), Expect = 1e-43, Method: Compositional matrix adjust."文本字符串中的Score值与Expect值。
    #!/usr/bin/perl -w
    use strict;
    
    my $line1="Score =  161 bits (407), Expect = 1e-43,   Method: Compositional matrix adjust.";
    my @result= ($line1=~ m/Score\s*=\s*([\d\.\,]+)\s*bits\s*\(\d+\)\,\s*Expect\s*=\s*(\S+),/);
    print "@result\n";
    
    正则表达式捕获
    此处的正则表达式比较长,(\S+)存疑,我替换成(\w+)就输出为空白了,奇怪。慢慢理解下~

    3、正则替换

    模式为 s/ <1> / <2> /

    • s表示替换,不可省略;
    • <1> 为匹配内容,即被替换的文本;
    • <2> 为替换的文本;若为空,就表示删除;
    #!/usr/bin/perl -w
    use strict;
    
    my $line="hello,world!";
    $line=~ s/world/China/;   #替换单词
    
    $line=~ s/^/Nihao,/;  #在行首添加内容
    $line=~ s/$/hello!/;  #在行尾添加
    
    $line=~ s/hello/ /g;  #删除所有的hello 
    # g修饰符表示全局替换,否则只会删除第一个;
    
    my $num+=($line=~ s/hello!/ /g);
    # 赋值给变量的值是成功替换的次数,在统计特定文本个数是有用。
    print "$line\n";
    print "$num\n";
    

    补充1:一一对应替换

    • 示例:获得序列的互补序列,即A-T、T-A、C-G、G-C四种替换(N碱基不变);
    • 不能使用s模式;可以使用tr模式
    #!/usr/bin/perl -w
    use strict;
    
    my $seq="TTATCCCTAAAATNGTNNNAGTATAAACATAAGA";
    # my $r_seq=reverse $seq;
    # 如果想要获得反向互补序列,可以先reverse一下
    my $r_seq=$seq;
    $r_seq=~ tr/ATCG/TAGC/;
    
    print "$seq\n";  #原始序列
    print "$r_seq\n";  # 互补序列
    
    互补序列

    补充2:大小写替换

    my $seq="TTATCCCTAAAATNGTNNNAG";
    $seq=~ s/(\w+)/\U$1/g;  #全部变成大写
    $seq=~ s/(\w+)/\L$1/g;  #全部变成小写
    $seq=~ s/(\w+)/\u$1/g;  #首字母大写
    

    巧妙利用了( )捕获与$1变量的关系。

    补充3:贪婪匹配(替换)

    • +*? 等都尽可能的多匹配长字符串,即贪婪匹配
    my $seq="ATGTCCC1TAAAATNGTNN2TAA";
    if ($seq=~ /^ATG(.+)TAA/i) {
        print "$1\n";   
    } 
    
    • 此例中,通过再加?,取消贪婪、匹配最短序列。
    my $seq="ATGTCCC1TAAAATNGTNN2TAA";
    if ($seq=~ /^ATG(.+?)TAA/i) {
        print "$1\n";   
    } 
    
    贪婪匹配

    相关文章

      网友评论

        本文标题:perl入门07:正则表达式(基础)

        本文链接:https://www.haomeiwen.com/subject/hkvvvhtx.html