美文网首页生物信息学
学生信的那些事儿之九 - Linux基础之正则表达式

学生信的那些事儿之九 - Linux基础之正则表达式

作者: 李白爱吃橙子 | 来源:发表于2019-06-21 12:00 被阅读54次

    什么是正则表达式?

    讲真"正则"这个词真的挺抽象,汉语里应该没有这个组合,不知道为什么这样翻译,倒是对应的英文更好理解一些。正则表达式( Regular Expression, RE )是处理字符串的方法,通过一些特殊字符的排列(或者说是模式模板),以行为单位,可以实现查找、删除、替换某特定字符串的功能。好像还是有些不明白,按我的理解来说,正则表达式就像是一张网,用来捕鱼的网,正则表达式中的特殊字符组合就相当于网眼的大小。通过调整字符组合就可以调整网眼尺寸,从而实现捕捉想要捕捉尺寸的鱼,同理,通过正则表达式就可以实现对数据的筛选分流,快速筛选出目标文本(字符,or anything you want)。

    为什么要学正则表达式

    上篇介绍了两个文本编辑器sed和gawk,在处理文本时用到的命令(模式)就是正则表达式,正则表达式有多丰富,两款工具的功能就有多强大。正则表达式种类很多,其实现需要正则表达式引擎( regular expression engine ),正则表达式引擎是一套底层软件,负责解释正则表达式模式并使用这些模式进行文本匹配。Linux中有两种主流正则表达式引擎:

    • 基础正则表达式( basic regular expression, BRE)引擎
    • 扩展正则表达式( exended regular expression, ERE)引擎

    基础正则表达式( BRE )

    1. 纯文本

    最最基本的BRE模式就是匹配数据流中的文本字符。这部分上篇已经讲过,话不多说,直接看示例:

    # sed示例
    $ echo "This is a test" | sed -n '/test/p'
      This is a test
    $
    # gawk示例
    $ echo "This is a test" | gawk '/test/{print $0}'
      This is a test
    $
    # 需要注意的
      正则表达式匹配模式很挑剔,所以匹配的时候会区分大小写;
      在正则表达式中,无需写出整个单词,只要定义的文本出现在数据流中,正则表达式就能匹配;
      正则表达式中,空格和其他字符并无区别;
    

    2. 锚字符

    锁定在行首:脱字符( ^ ) 锁定在行尾:美元符( $ )

    比较简单,不多说,看示例就能懂:

    # 行首(必须是精确匹配)
    $ echo "This is a test" | sed -n '/^This/p'
      This is a test
    $
    # 行尾(必须是精确匹配)
    $ echo "This is a test" | sed -n '/test$/p'
      This is a test
    $
    

    3. 点号字符

    点号字符( . )属于特殊字符,用来匹配除换行符之外的任意单个字符(必须匹配一个字符,否则模式就不成立)。

    还是举例说话:

    # 一行一行地看匹配模式
    $ cat test.txt
      This is a beautiful world.
      The cat is sleeping.
      That is a very nice hat.
      This test is at line four.
      at ten o`clock we`ll go home.
    $
    $ sed -n '/.at/p' test.txt
      The cat is sleeping.
      That is a very nice hat.
      This test is at line four.
    $
    

    4. 字符组

    如果想要限定待匹配的字符的具体值,点号字符就力不从心了。这个时候需要字符组( character class ), 字符组可以用方括号( [ ] )定义,可在其中写入想要的字符。看示例:

    # 这是个极简单的例子,用法其实还有很多,比如连用几个字符组,区间字符(数字)等~
    $ sed -n '/[ch]at/p' test.txt
      The cat is sleeping.
      That is a very nice hat.
    $
    

    5. 排除性字符组

    顾名思义,跟字符组是相反的,没错,用的特殊字符就是脱字符^,简单到不想多说。

    6. 区间

    可以说是字符组的一个延伸,比如设置数字匹配模式时,如果想匹配0到9之间的任意数字,可以用下面的方式:

    # 常规的字符组表示法
      [0123456789]
    # 区间表示法,简单很多,起始中间用 "-"
      [0-9]
    # 以此类推,字母也一样的,比如a-z,A-Z
      [a-z], [A-Z]
    # 具体用法参照上面字符组即可
    

    7. 特殊字符组

    看名称就知道,也是字符组,也算是普通字符组的延伸,不多说,直接摘抄如下:

    [[:alpha:]]             匹配任意字母字符,不区分大小写
    [[:alnum:]]             匹配任意字母数字字符0-9,a-z,A-Z
    [[:blank:]]             匹配空格或制表符
    [[:digit:]]             匹配0-9之间的数字
    [[:lower:]]             匹配小写字母字符a-z
    [[:print:]]             匹配任意可打印字符
    [[:punct:]]             匹配标点符号
    [[:space:]]             匹配任意空白字符:空格、制表符、NL、FF、VT和CR
    [[:upper:]]             匹配任意大写字母字符A-Z
    # 同样的,用法参照普通字符组
    

    7. 星号

    这里的星号()和Linux命令中的通配符不一样,在正则表达式中,字符后面放置星号表明该字符必须在匹配模式的文本中出现0次或多次*。看示例体会一下:

    # 认真体会下最后一个
    $ echo "bt" | sed -n '/b[ae]*t/p'
      bt
    $ echo "bat" | sed -n '/b[ae]*t/p'
      bat
    $ echo "bet" | sed -n '/b[ae]*t/p'
      bet
    $ echo "btt" | sed -n '/b[ae]*t/p'
      btt
    

    扩展正则表达式( ERE )

    正则表达式模式中使用文本字符时,对于一些特殊字符需要格外注意,因为一些字符在正则表达式中是有特别含义的,包括:

    . * [] ^ $ {} \ + ? | ()

    其中一些字符在基础正则表达式中已经介绍,那扩展正则表达式又扩展在哪里呢?主要是几个只能够被gawk识别,但是sed却无法识别的字符:? + {} | ()

    1. 问号

    问号与星号作用类似,区别在于问号表明前面的字符可以出现0次或1次(没有其他值)。看示例理解:

    # 需要理解所谓的精确匹配,以及方括号的含义
    $ echo "bt" | gawk '/b[ae]?t/{print $0}'
      bt
    $ echo "bat" | gawk '/b[ae]?t/{print $0}'
      bat
    $ echo "bot" | gawk '/b[ae]?t/{print $0}'
    $  
    $ echo "bet" | gawk '/b[ae]?t/{print $0}'
      bet
    $ echo "baet" | gawk '/b[ae]?t/{print $0}'
    $
    $ echo "beat" | gawk '/b[ae]?t/{print $0}'
    $
    $ echo "beet" | gawk '/b[ae]?t/{print $0}'
    $
    

    2. 加号

    同于与星号功能类似,同样也有细微区别。加号表示前面字符可以出现1次或多次,且必须至少出现1次。不想举例了~

    3. 花括号

    跟方括号可以限定具体的匹配字符一样,花括号可以实现正则表达式中对某个模式具体重复次数的限定,有两种形式:

    • m:正则表达式准确出现几次
    • m,n: 正则表达式至少出现m次,至多n次

    比较特殊的是,gawk需要指定 - -re - interval 命令选项才可以识别正则表达式间隔。示例:

    $ echo "bt" | gawk --re -interval '/be{1}t/{print $0}'
      
    $ echo "bet" | gawk --re -interval '/be{1}t/{print $0}'
      bet
    $ echo "bt" | gawk --re -interval '/be{1,2}t/{print $0}'
      
    $ echo "bet" | gawk --re -interval '/be{1,2}t/{print $0}'
      bet
    

    4. 管道符号

    简单说一句话:管道符表示or(或)的关系,只需满足其中一个即可。示例如下:

    $ echo "The cat is asleep" | gawk '/cat|dog/{print $0}'
      The cat is asleep
    $ echo "The dog is asleep" | gawk '/cat|dog/{print $0}'
      The dog is asleep
    $ echo "The sheep is asleep" | gawk '/cat|dog/{print $0}'
    $
    

    5. 圆括号-表达式分组

    圆括号可以实现正则表达式的分组,分组后,每个组会被视为一个标准字符。看示例说话:

    # 圆括号里面的字符可视为一个整体
    $ echo "Sat" | gawk '/Sat(urday)?/{print $0}'
      Sat
    $ echo "Saturday" | gawk '/Sat(urday)?/{print $0}'
      Saturday
    

    Linux基础部分打算暂且就学这么多先,下一篇开始转录组学数据的实操。

    相关文章

      网友评论

        本文标题:学生信的那些事儿之九 - Linux基础之正则表达式

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