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


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

本文目录结构预览:

  • 一、简介
  • 二、汇总表
  • 三、历史版本
    1、版本区别:
    2、区别总结
  • 四、案例说明
    1、匹配行和单词(锚的使用)
    2、匹配任意字符
    3、字符范围匹配 与 预定义字符类
    4、重复组
  • 五、参考

一、简介

正则表达式(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 字符串的行,并且 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 著 张杰良 译