美文网首页Linux终极玩家
Linux深入探索10-正则表达式

Linux深入探索10-正则表达式

作者: 四月不见 | 来源:发表于2022-01-15 23:57 被阅读0次

    ----- 最近更新【2022-01-15】-----

    一、简介

    正则表达式(regular expression)通常简写为 regex 或 re,是一种指定字符串模式的简洁方式。

    正则表达式可以用于许多种编程语言中,例如:Awk、C、C++、C#、Java、Perl、PHP、Python、Ruby、Tcl和VB.NET等。尽管正则表达式在各个程序之间有所不同,但是基本思想总是相同的。

    二、汇总表

    正则表达式的强大来自拥有特殊含义的元字符和缩写的使用。在正则表达式中,普通字符匹配自身,特殊字符拥有特殊的含义。

    元字符:

    元字符 含义 例子
    . 除新行字符外,匹配任意的单个字符
    ^ 锚:匹配行的开头
    $ 锚:匹配行的末尾
    \< 锚:匹配单词的开头
    \> 锚:匹配单词的末尾
    [list] 字符类:匹配 list 中的任何字符
    [^list] 匹配不在 list 中的任何字符
    ( ) 组:视为一个单独的单元
    | 交变:匹配选择之一
    \ 引用:从字面上解释元字符

    重复运算符:

    运算符 含义 例子
    * 匹配 0 次或多次
    + 匹配 1 次或多次
    ? 匹配 0 次或 1 次
    {n} 限定:匹配 n 次
    {n,} 限定:最少匹配 n 次
    {0,m} 限定:最多匹配 m 次
    {,m} 限定:最多匹配 m 次
    {n,m} 限定:最少匹配 n 次,最多匹配 m 次

    注意:有一些程序不支持{,m},因为它不是标准的。

    预定义字符类:

    类似于 含义 例子
    [:lower:] a-z 小写字母
    [:upper:] A-Z 大写字母
    [:alpha:] A-Za-z 大小写字母
    [:alnum:] A-Za-z0-9 大小写字母、数字
    [:digit:] 0-9 数字
    [:punct:] 标点符号
    [:blank:] 空格或制表符(空白符)

    注意:方括号和冒号是名称的一部分

    三、历史版本

    Unix 支持两种主要的正则表达式变体:一个现代版本,一个以前的废弃版本。

    现代版本的正则表达式是扩展正则表达式(extended regular expression),或者简称为 ERE。它是当前的标准,属于 IEEE 1003.2 标准(POSIX 的一部分)。

    以前版本的正则表达式是 基本正则表达式(basic regular expression),或者简称为 BRE。现在 BRE 已经被废弃,保留它们只是为了与旧程序兼容。

    例如 sed 程序默认使用的就是基本正则表达式,需要使用扩展正则表达式则要带上相应选项,即sed -E

    1、版本区别:

    基本正则表达式 和 扩展正则表达式 之间的主要区别就是,对于基本正则表达式来说,有些特定的元字符不能使用,而其它元字符必须使用反斜线(\)引用。

    不能使用的元字符有:?+|
    必须转义的元字符有:{ }( )

    2、区别总结

    扩展正则表达式 基本正则表达式 含义
    { } \{ \} 定义一个限定
    ( ) \( \) 定义一个组
    可模拟为:\{ 0,1\} 匹配 0 次或 1 次
    + 可模拟为:\{ 1,\} 匹配 1 次或 多 次
    | 不支持 交变:匹配选项中的一个
    [:name:] 不支持 预定义字符类

    四、案例说明

    测试文本 letter.txt 的内容如下:

    [nosee@instance-4 ~]$ cat letter.txt 
    Dear Miss Hanff:
        Thank you very much for your letter,
    I appreciate your kindness in telling me
    the cloth I worked has given you so moch
    pleasure. I only wish I could do more.
    I expect Mrs. Doel has told you I am
    getting on in years so I am unable to do
    as much as I used to. It is always a joy
    to me when my work gets into the hands
    of someone who appreciates it.
        I see Mrs. Doel most days, she often
    speaks of you. Perhaps I may see you if
    you come to England.
        Again thanking you
    
                Jan. 29th,1952
                        Yours very sincerely,
                        Mary Boulton
    

    1、匹配行和单词(锚的使用)

    正则表达式中的“锚”,也就是使用以下4种元字符:

    元字符 含义
    ^ 锚:匹配行的开头
    $ 锚:匹配行的末尾
    \< 锚:匹配单词的开头
    \> 锚:匹配单词的末尾

    1)行的开头与末尾

    例:匹配所有包含有 you 字符中的行

    [nosee@instance-4 ~]$ grep you letter.txt 
        Thank you very much for your letter,
    I appreciate your kindness in telling me
    the cloth I worked has given you so moch
    I expect Mrs. Doel has told you I am
    speaks of you. Perhaps I may see you if
    you come to England.
        Again thanking you
    

    例:匹配所有包含有 you 字符串 并且 you 字符串位于行开头的行

    [nosee@instance-4 ~]$ cat letter.txt | grep '^you'
    you come to England.
    

    例:匹配所有包含有 you 字符串 并且 you 字符串位于行末尾的行

    [nosee@instance-4 ~]$ cat letter.txt | grep 'you$'
        Again thanking you
    

    Tip:搜索空行可以这样:grep '^$'

    2)单词的开头与末尾

    例:查找所有包含有 le 字符串的行
    [图片上传中...(image.png-5b6b3d-1642238499630-0)]

    [nosee@instance-4 ~]$ cat letter.txt | grep le
        Thank you very much for your letter,
    pleasure. I only wish I could do more.
    getting on in years so I am unable to do
    

    例:查找所有包含有 le 字符串的行,并且 le 字符串要位于单词开头

    [nosee@instance-4 ~]$ cat letter.txt | grep '\<le'
        Thank you very much for your letter,
    

    例:查找所有包含有 le 字符串的行,并且 le 字符串要位于单词末尾

    [nosee@instance-4 ~]$ cat letter.txt | grep --color 'le\>'
    getting on in years so I am unable to do
    

    在正则表达式中,“单词”就是一个自包含,由字母、数字或者下划线字符构成的连续字符串。

    Tip:
    搜索完整单词可以这样:grep '\<单词\>'
    有些系统可以使用 \b来代替 \<\>,如grep '\b单词\b'

    2、匹配任意字符

    元字符:.(点号),匹配任意的单个字符,除新行字符外。(新行字符标记一行的末尾)

    例:匹配一个 “ Y 或 y 开头,中间3个任意字符,以 s 结尾” 的单词

    [nosee@instance-4 ~]$ cat letter.txt | grep '\<[Yy]...s\>'
    getting on in years so I am unable to do
                        Yours very sincerely,
    

    3、字符范围匹配 与 预定义字符类

    使用预定义字符类时,唯一需要注意的一点就是,方括号实际上是名称的一部分。因此,使用时必须在包含第二组方括号,以维持正确的语法。

    例:查找包含有4个连续数字的行

    [nosee@instance-4 ~]$ cat letter.txt | grep -E '[0-9]{4}'
                Jan. 29th,1952
    [nosee@instance-4 ~]$ cat letter.txt | grep -E '[[:digit:]]{4}'
                Jan. 29th,1952
    

    注:
    以上两个正则表达式含义是一样的。
    grep-E 选项是为了使用扩展正则表达式。
    连字符-也是元字符,当需要匹配-本身时也需要转义\-

    例:匹配至少包含有10个字母的单词

    [nosee@instance-4 ~]$ cat letter.txt | grep -E '[[:alpha:]]{10,}'
    I appreciate your kindness in telling me
    of someone who appreciates it.
    [nosee@instance-4 ~]$ cat letter.txt | grep -E '[A-Za-z]{10,}'
    I appreciate your kindness in telling me
    of someone who appreciates it.
    

    例:搜索linux目录/bin下,名字为 两个a-g字母组成的单词的程序

    [nosee@instance-4 ~]$ ls /bin | grep -E '^[a-g]{2}$'
    ab
    dd
    df
    

    例:统计linux目录/bin下,名字为两个小写字母组成的单词的程序共有多少个

    [nosee@instance-4 ~]$ ls /bin | grep -Ec '^[a-z]{2}$'
    28
    

    4、重复组

    例:匹配任何 “i 或 I 开头” 然后接 “一个小写字母” 再接 “一个任意字符”,并且 “该模式出现两次” 的字符串

    [nosee@instance-4 ~]$ cat letter.txt | grep -E '([Ii][a-z].){2}'
    as much as I used to. It is always a joy
    

    参考:

    书箱:《Unix & Linux 大学教程》第二十章 (美)Harley Hahn 著 张杰良 译

    相关文章

      网友评论

        本文标题:Linux深入探索10-正则表达式

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