正则表达式

#正则表达式
    定义正则表达式
    正则表达式基础
    扩展正则表达式
    创建正则表达式
一、定义:正则表达式是你所定义的模式模板,能够在处理数据时使用正则表达式对数据进行模式匹配。正则表达式模式利用通配符来描述数据流中的一个或多个字符。
    $ ls -al da*
二、正则表达式基础
    1、正则表达式类型
    正则表达式是通过正则表达式引擎实现的,流行的有两种: POSIX基础正则表达式(basic regular expression,BRE)引擎; POSIX扩展正则表达式(extended regular expression,ERE)引擎
        sed编辑器只符合了BRE引擎规范的子集,这是出于速度方面的考虑导致的。
        gawk程序用ERE引擎来处理它的正则表达式模式
    2、BRE
    第一条原则:正则表达式模式都区分大小写
    ①纯文本
        $ echo "This is a test" | sed -n '/this/p'
        $    -- 大小写不符,未匹配
        $ echo "The books are expensive" | sed -n '/book/p'    -- 在正则表达式中,你不用写出整个单词
        The books are expensive
        $ echo "This is line number 1" | sed -n '/ber 1/p'    -- 使用空格加数字。在正则表达式中,空格和其他的字符并没有什么区别
        This is line number 1
    ②特殊字符
        正则表达式识别的特殊字符包括:
            .*[]^${}\+?|()
        不能在文本模式中单独使用这些字符,需要转义反斜线(\)
            $ cat data2
            The cost is $4.00
            $ sed -n '/\$/p' data2    -- 查找文本中的$,因为$是特殊字符,所以需要转义
            The cost is $4.00
        在sed编辑器或gawk程序中,正斜线(/)虽然不是特殊字符但也需要转义
            $ echo "3 / 2" | sed -n '/\//p'
            3 / 2
    ③锚字符
        行首锚点:锁定在行首,脱字符( ^ )定义从数据流中文本行的行首开始的模式
            $ echo "Books are great" | sed -n '/^Book/p'
            Books are great
        行尾锚点:锁定在行尾,特殊字符美元符( $ )定义了行尾锚点
            $ echo "This is a good book" | sed -n '/book$/p'
            This is a good book
        组合锚点
            $ cat data4
            this is a test of using both anchors
            I said this is a test
            this is a test
            I'm sure this is a test.
            $ sed -n '/^this is a test$/p' data4
            this is a test
            $
            $ cat data5
            This is one test line.
            
            This is another test line.
            $ sed '/^$/d' data5    -- 过滤掉数据流中的空白行,使用d删除
            This is one test line.
            This is another test line.
    ④点号字符
    特殊字符点号用来匹配除换行符之外的任意单个字符。它必须匹配一个字符,如果在点号字符的位置没有字符,那么模式就不成立
        $ cat data6
        This is a test of a line.
        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' data6
        The cat is sleeping.
        That is a very nice hat.
        This test is at line four.
        $
    ⑤字符组
    使用方括号来定义一个字符组。方括号中包含所有你希望出现在该字符组中的字符
        $ sed -n '/[ch]at/p' data6
        The cat is sleeping.
        That is a very nice hat.
        $ echo "Yes" | sed -n '/[Yy][Ee][Ss]/p'    -- 可以使用多个字符组
        Yes
        $ cat data8
        60633
        46201
        223001
        4353
        22203
        $ sed -n '
        > /^[0123456789][0123456789][0123456789][0123456789][0123456789]$/p    -- 只匹配五位数,需要使用首尾锚点
        > ' data8
        60633
        46201
        22203
        $
    ⑥排除型字符组
    字符组的开头加个脱字符(^),可以寻找组中没有的字符
        $ sed -n '/[^ch]at/p' data6
        This test is at line four.    -- 空格也属于字符,所以能够输出
    ⑦区间
    可以用单破折线符号在字符组中表示字符区间
        $ sed -n '/^[0-9][0-9][0-9][0-9][0-9]$/p' data8    -- 简化有效邮编查看
        60633
        46201
        45902
        $ sed -n '/[c-h]at/p' data6    -- 也适用于字母
        The cat is sleeping.
        That is a very nice hat.
        $ sed -n '/[a-ch-m]at/p' data6    -- 还可以在单个字符组指定多个不连续的区间a-c、h-m
        The cat is sleeping.
        That is a very nice hat.
    ⑧特殊的字符组
        BRE特殊字符组
          组                 描 述
        [[: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
        $ echo "abc" | sed -n '/[[:alpha:]]/p'
        abc
    ⑨星号
    在字符后面放置星号表明该字符必须在匹配模式的文本中出现0次或多次
        $ echo "iek" | sed -n '/s*/p'    -- 任意字符后跟*都会输出,判断该字符出现和不出现的情况都是成立的    
        iek
        $ echo "I'm getting a color TV" | sed -n '/colou*r/p'    -- 模式中的 u* 表明字母u可能出现或不出现在匹配模式的文本中。用于单词错误拼写
        I'm getting a color TV
        $ echo "this is a regular pattern expression" | sed -n '
        > /regular.*expression/p'    -- 点号特殊字符和星号特殊字符组合起来,能够匹配任意数量的任意字符
        this is a regular pattern expression
        $ echo "btt" | sed -n '/b[ae]*t/p'    -- [ae]*出现0次,成立
        btt
        $ echo "baakeeet" | sed -n '/b[ae]*t/p'
        $    -- [ae]* ae的任意组合都成立,但a、e中不能有其他字符
三、扩展正则表达式
    ①问号
    问号表明前面的字符可以出现0次或1次,不会匹配多次出现的字符
        $ echo "bt" | gawk '/be?t/{print $0}'
        bt
        $ echo "bet" | gawk '/be?t/{print $0}'
        bet
        $ echo "beet" | gawk '/be?t/{print $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次
        $ echo "beeet" | gawk '/be+t/{print $0}'
        beeet
        $ echo "beet" | gawk '/be+t/{print $0}'
        beet
        $ echo "bet" | gawk '/be+t/{print $0}'
        bet
        $ echo "bt" | gawk '/be+t/{print $0}'
        $
        $ echo "bt" | gawk '/b[ae]+t/{print $0}'    -- 同样适用于数组
        $
        $ echo "bat" | gawk '/b[ae]+t/{print $0}'
        bat
        $ echo "bet" | gawk '/b[ae]+t/{print $0}'
        bet
        $ echo "beat" | gawk '/b[ae]+t/{print $0}'
        beat
        $ echo "beet" | gawk '/b[ae]+t/{print $0}'
        beet
        $ echo "beeat" | gawk '/b[ae]+t/{print $0}'
        beeat
    ③使用花括号
    ERE中的花括号允许你为可重复的正则表达式指定一个上限
    m :正则表达式准确出现 m 次。
    m, n :正则表达式至少出现 m 次,至多 n 次。
        $ echo "bt" | gawk --re-interval '/be{1}t/{print $0}'
        $
        $ echo "bt" | gawk --re-interval '/be{1,2}t/{print $0}'
        $
        $ echo "bet" | gawk --re-interval '/be{1,2}t/{print $0}'
        bet
        $ echo "beet" | gawk --re-interval '/be{1,2}t/{print $0}'
        beet
        $ echo "beeet" | gawk --re-interval '/be{1,2}t/{print $0}'
        $
        $ echo "bt" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'    -- 适合于数组
        $
        $ echo "bat" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
        bat
        $ echo "bet" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
        bet
        $ echo "beat" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
        beat
        $ echo "beet" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
        beet
        $ echo "beeat" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
        $
        $ echo "baeet" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
        $
        $ echo "baeaet" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
        $
    ④管道符号
        管道符号允许你在检查数据流时,用逻辑 OR 方式指定正则表达式引擎要用的两个或多个模式。如果任何一个模式匹配了数据流文本,文本就通过测试
            $ echo "The dog is asleep" | gawk '/cat|dog/{print $0}'
            The dog is asleep
            $ echo "The sheep is asleep" | gawk '/cat|dog/{print $0}'
            $
            $ echo "He has a hat." | gawk '/[ch]at|dog/{print $0}'
            He has a hat.
    ⑤表达式分组
        当你将正则表达式模式分组时,该组会被视为一个标准字符
            $ echo "Sat" | gawk '/Sat(urday)?/{print $0}'
            Sat
            $ echo "Saturday" | gawk '/Sat(urday)?/{print $0}'
            Saturday
            $
            $ echo "cat" | gawk '/(c|b)a(b|t)/{print $0}'
            cat
            $ echo "cab" | gawk '/(c|b)a(b|t)/{print $0}'
            cab
            $ echo "bat" | gawk '/(c|b)a(b|t)/{print $0}'
            bat
            $ echo "bab" | gawk '/(c|b)a(b|t)/{print $0}'
            bab
            $ echo "tab" | gawk '/(c|b)a(b|t)/{print $0}'
            $
            $ echo "tac" | gawk '/(c|b)a(b|t)/{print $0}'
            $
四、创建正则表达式
    目录文件计数:
        $
        mypath=$(echo $PATH | sed 's/:/ /g')
        count=0
        for directory in $mypath
        do
        check=$(ls $directory)
        for item in $check
        do
        count=$[ $count + 1 ]
        done
        echo "$directory - $count"
        count=0
        done
        $
    验证电话号码
     美国的四种形式电话号码验证
        (123)456-7890
        (123) 456-7890
        123-456-7890
        123.456.7890
        ^\(?[2-9][0-9]{2}\)?(| |-|\.)[0-9]{3}( |-|\.)[0-9]{4}$
    解析邮件地址
        username@hostname
        username 值可用字母数字字符以及以下特殊字符:
        点号
        单破折线
        加号
        下划线
        hostname部分由一个或多个域名和一个服务器名组成
        对于顶级域名,有一些特殊的规则。顶级域名只能是字母字符,必须不少于二个字符(国家或地区代码中使用),并且长度上不得超过五个字符
        ^([a-zA-Z0-9_\-\.\+]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$

 

posted on 2019-07-17 10:24  丿星痕☆森文  阅读(195)  评论(0编辑  收藏  举报

导航