美文网首页程序员想法
再探正则表达式

再探正则表达式

作者: ElephantKing | 来源:发表于2019-12-24 17:49 被阅读0次

    历史发展

    根本不想谈发展史,概况起来就是:还是不说了。
    总之发展到现在,可能有如下几个关键词:正则表达式,基础正则,扩展正则,POSIX正则标准,PCRE正则标准。下面一个个稍微解释一下。
    正则表达式:是一个最宽泛的概念,基本不涉及具体的实现和语法的描述性的词,是一个笼统的概念而已。就好像我们说笔记本电脑一样,仅仅描述这样一个物件,什么CPU,什么品牌,什么内存并没有描述。
    基础正则(BRE):与扩展正则(ERE)相对应,是正则表达文法发展之初的一个雏形,支持的正则符号比较少(但是在最初已经非常好用了)。随着正则文法的推广和使用,在基础正则的符号基础语法基础上做了更多的扩展,形成了扩展正则(实际上就是添加了正则符号和正则语法)
    POSIX正则标准:为什么出现两个标准就不展开了,这都是历史问题。好在现在只有两个标准,并且这两个标准差别并不是很大,后面会讲。花开两朵,各表一枝,POSIX标准下又根据发展的时间线分为了基础正则和扩展正则,两者有着细微的语法差异,正则符号并无差异。
    PCRE正则标准:后期发展形成,所以一步登基,直接支持扩展正则。

    关键字符表

    基础正则符号集合:

    *:前一个字符任意次重复
    .:任意一个字符
    ^:行首,或用在[^]语法中表示非
    $:行尾
    []:集合中的任意字符
    \:转义字符,让元字符变为普通字符,或用来支持扩展正则符号
    \<:单词的开头
    \>:单词的结尾
    

    扩展正则符号集合:

    {}:前一个字符的次数重复,在基础正则语法中变成\{\}
    ?:前一个字符0或1次
    +:前一个字符的至少1次重复
    ():表示一个整体,在基础正则语法中变成\(\)
    |:表示或,匹配一组可选的字符,在基础正则语法中变成\|
    

    POSIX标准的shorthand

    POSIX标准的基础正则语法和扩展正则语法都能用,PCRE标准不能用
    [:upper:]:大写字母,[[:upper:]]任意一个大写字母,其余用法同
    [:lower:]:小写字母
    [:alpha:]:字母
    [:alnum:]:字母或数字
    [:digit:]:数字
    [:blank:]:空格和TAB
    [:word:]:数字、字符、下划线
    [:print:]:可打印字符
    

    PCRE标准的shorthand

    PCRE标准能用,POSIX标准不能用
    \c:控制字符
    \s:空白
    \S:非空白符
    \d:数字
    \D:非数字
    \w:数字字符下划线
    \W:非\w
    \x:16进制数字
    \O:8进制数字
    

    上面就解释了,为啥有些正则能在某个命令中正确执行,放到别的命令中就报错了,多半是不同命令支持的标准不一样。
    使用BRE语法的命令有:grep、ed、sed、vim
    使用ERE语法的命令有:egrep、awk、emacs

    差异示例

    由于我使用的系统支持POSIX标准的正则,这里只展示基础正则和扩展正则的差异,都用sed命令来展示。测试文件a.txt内容如下:

    aabbcc
    aaaabbb
    abcdddabc
    abcdddbbc
    
    • 前一个字符重复N此的符号{}
    # BRE
    sed -n '/a\{2,\}/'p a.txt
    # ERE
    sed -n -r '/a{2,}/'p a.txt
    # output:
    # aabbcc
    # aaaabbb
    
    • 前一个字符重复0或1次
    # BRE
    sed -n '/da\?b/'p a.txt
    # ERE
    sed -n -r '/da?b/'p a.txt
    # output:
    # abcdddabc
    # abcdddbbc
    
    • 前一个字符重复至少一次
    # BRE
    sed -n '/aa\+/'p a.txt
    # ERE
    sed -n -r '/aa+/'p a.txt
    # output:
    # aabbcc
    # aaaabbb
    
    • 匹配组
    # BRE
    sed -n '/\([abc]\{3,\}\)ddd\1/'p a.txt
    # ERE
    sed -n '/([abc]{3,})ddd\1/'p a.txt
    # output:
    # abcdddabc
    
    • 匹配组间的或关系
    # BRE
    sed -n '/dab\|dbb/'p a.txt
    # ERE
    sed -n '/dab|dbb/'p a.txt
    # output:
    # abcdddabc
    # abcdddbbc
    

    以上就是POSIX标准下,基础正则和扩展正则语法上的差异,即:基础正则语法要使用上面这些符号用作特殊意义时,需要加反斜杠,用作普通字符时则不需要。相反,扩展正则语法使用上面这些符号用作特殊意义时,不需要加反斜杠,反而用作普通字符时则需要加反斜杠。

    后记

    之前模模糊糊了解了点正则的语法,但是总体上还不是很清楚,尤其是自己在写sed命令时和在使用正则表达式在线进行比对时发生的不一致,让我苦恼万分,行文至此,其中的曲折已了然于心。sed命令是POSIX标准,不能使用PCRE标准的shorthand系列字符。同样的,正则表达式在线使用的是PCRE标准,不能使用POSIX标准的shorthand。简单的一句话,却需要一个下午来实践、实验和证明,希望看到这篇文章的你不要再走弯路。

    相关文章

      网友评论

        本文标题:再探正则表达式

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