正则表达式是一种可供Linux工具过滤文本的自定义模板,Linux工具(如sed、gawk)会在读取数据时使用正则表达式对数据进行模式匹配。
正则表达式使用元字符来描述数据流中的一个或多个字符。它是由正则表达式引擎实现的。正则表达式引擎是一种底层软件,负责解释正则表达式并用这些模式进行文本匹配。
最流行的正则表达式引擎有两种:
POSIX基础正则表达式(basic regular expression,BRE)引擎;
POSIX扩展正则表达式(extended regular expression,ERE)引擎。
一、BRE模式
最基本的BRE模式是匹配数据流中的文本字符。
1、普通文本
正则表达式匹配的第一条原则:区分大小写。

正则表达式中也可以使用空格和数字:
2、特殊字符
正则表达式能识别的特殊字符如下:
* [] ^ $ {} \ + ? | ()
如果要将某个特殊字符视为普通字符,则必须用反斜线(\)将其转义。
bash
# 匹配文本中的美元符号$
sed -n '/\$/p' test1.txt

转义反斜线(\):

正斜线(/) 虽然不属于正则表达式中的特殊字符,但也需要进行转义,否则会报错。

3、锚点字符
有两个特殊字符可以用来将正则表达式模式锁定在数据流中的行首或者行尾,这两个特殊字符被称为锚点字符。
锚定行首
**脱字符(^)**可以指定位于数据流中文本行行首的模式,如果模式出现在行首之外的其它地方,则正则表达式无法匹配。
使用脱字符时必须将其置于正则表达式之前。

如果将脱字符放在正则表达式开头之外的位置,sed就会将其视为普通字符进行匹配。

如果只是匹配脱字符,则不用进行转义。
如果要匹配脱字符及其它文本,则需要将脱字符进行转义。

锚定行尾
特殊字符美元符号($)定义了行尾锚点。将其放在正则表达式之后则表示数据行必须以该模式结尾。

组合锚点
查找只含有特定文本模式的数据行。

将两锚点直接组合在一起,之间不加任何文本,可以过滤出数据流中的空行。
如下所示,指定的正则表达式会查找行首和行尾之间什么都没有的那些行,由于空行在两个换行符之间没有文本,所以正好被匹配到。
这是一种从文本中删除空行的一种不错的方法。
bash
sed '/^$/d' test1.txt

4、点号字符
点号字符匹配除换行符以外的任意单个字符 ,它必须匹配一个字符。

5、字符组
可以在正则表达式中定义用来匹配某个位置的一组字符。如果字符组中的某个字符出现在了数据流中,那就匹配成功。
方括号用于定义字符组,在方括号中加入希望出现在该字符组中的所有字符,就可以在正则表达式中像其它字符一样使用字符组了。
不确定某个字符的大小写时:

在单个正则表达式中可以使用多个字符组:

字符组中也可以使用数字:

6、排除型字符组
可以反转字符组的作用,即匹配字符组中没有的字符。只需在字符组的开头添加脱字符即可。
如下所示,匹配除c或h之外的任何字符以及文本模式。其中空格也能被匹配到。

7、区间
可以使用单连字符在字符组中表示字符区间。

还可以在字符组内指定多个不连续的区间。
如下所示,指定的范围是1到4个7到9。
8、特殊字符组
BRE有一些特殊的字符组。
|---------------------|-----------------------------------|
| [[:alpha:]] | 匹配任意字母字符,无论是大写还是小写 |
| [[:alnum:]] | 匹配任意字母数字字符,0~9,A~Z或a~z |
| [[:blank:]] | 匹配空格或制表符 |
| [[:digit:]] | 匹配0~9中的数字 |
| [[:lower:]] | 匹配小写字母a~z |
| [[:upper:]] | 匹配大写字母A~Z |
| [[:print:]] | 匹配任意可打印字符 |
| [[:punct:]] | 匹配标点符号 |
| [[:space:]] | 匹配任意空白字符:空格、制表符、换行符、分页符、回车符、垂直制表符 |
[BRE特殊字符组]
这些特殊字符组的用法和普通字符组的用法一样

9、星号*
匹配次数大于等于0次。
这个特殊符号常用于处理有常见拼写错误或在不同语言中有拼写变化的单词。
点号字符 与星号字符 组合起来,能够匹配任意数量的任意字符,一般用在数据流中两个可能相邻或不相邻的字符串之间。

星号还能用于字符组,指定可能在文本中出现0次或多次的字符组或字符区间。
不能出现字符组以外的其它字符,否则就无法匹配到。

二、ERE模式
gawk支持ERE模式,但sed不支持。前者可以使用大多数扩展的正则表达式符号,并能提供一些sed所不具备的额外过滤功能,但正因为如此,也使得gawk在处理数据时较慢。
1、问号?
匹配0次 或1次,不能匹配超过1次的多次。

问号也可以和字符组一起使用:如果字符组中的字符出现了0次或1次,就能匹配上;如果两个字符都出现或者其中一个出现了两次及以上,就不能匹配上。

2、加号+
匹配1次或多次,必须至少1次。

它也可以用于字符组上,用法和星号、问号一样。

3、花括号{}
可为正则表达式指定字符或字符组出现的可重复次数,称之为区间,有以下两种方式:
- m:正则表达式恰好出现m次;
- m,n:正则表达式至少出现m次,至多出现n次。
默认情况下,gawk不识别正则表达式区间,必须指定gawk的命令行选项**--re-interval**才行。
如下所示,只匹配一次e:

可以同时指定区间的下限 和上限:

也可以用在字符组上:
字母a或e在文本模式中只出现了1~2次,则正则表达式匹配成功,否则,不成功。
字母a和e出现的次数加起来最多只能是2次。
4、竖线符号|
竖线符号允许在检查数据流时,以逻辑OR方式指定正则表达式引擎要使用的两个或多个模式。如果其中任何一个模式成功匹配,就视为匹配成功,否则,则匹配失败。
格式:expr1|expr2|...
正则表达式和竖线符号之间不能有空格,否则竖线符号会被认为是正则表达式模式的一部分,

竖线符号两侧的子表达式可以采用正则表达式可用的任何模式符号,包括字符组。
如下所示,该正则表达式可以匹配cat、hat和dog。

5、正则表达式分组
可以用圆括号对正则表达式进行分组。分组之后,每一组都会被视为一个整体,可以像对普通字符一样对该组应用特殊字符。
如下所示,该正则表达式可以让正则表达式能够匹配Sunday或者Sun。

最常见的用法是将分组和竖线符号结合起来。
