首页 > 编程笔记

正则表达式语法详解

Linux 系统中,根据 POSIX 规范可以将正则表达式分为 2 种,标准正则表达式和扩展正则表达式。本节就对它们做详细地讲解。

标准正则表达式

标准正则表达式又称基本正则表达式,是最早指定的正则表达式规范。

表达式字符

基本正则表达式字符及其含义如表 1 所示。

表 1 基本正则表达式字符及其含义
字 符 含 义
^ 匹配字符串的开头。如 ^word,搜索以 word 开头的内容
$ 匹配字符串的结尾。如 word$,搜索以 word 结尾的内容
^$ 表示空行,不是空格
. 匹配任意单个字符(不匹配空行)
\ 匹配转义后的字符。如 \. 只表示小数点
* 重复之前的字符或文本 0 个或多个,之前的文本或字符连续 0 次或多次
.* 匹配任意多个字符
^.* 以任意多个字符串开头,.* 尽可能多
[ ] 匹配集合中的任意单个字符,括号中为一个集合
[x-y] 匹配连续的字符串范围
[^] 匹配否定,对括号中的集合取反
\{n,m\} 匹配前一个字符重复 n 到 m 次
\{n,\} 匹配前一个字符重复至少 n 次
\{n\} 匹配前一个字符重复 n 次
\(\) 将“\(”与“\)”之间的内容存储在“保留空间,最大存储 10 个。
\n 通过 \1 至 \10 调用保留空间的内容

在正则表达式模式中使用文本字符时,需要注意以下几点:
1) 如果使用某个特殊字符作为文本字符,需要进行转义。在转义特殊字符时,需要在它前面加上一个特殊字符告诉正则表达式将该字符当作普通的文本字符。这个特殊字符就是反斜线“\”。

因为反斜线“\”是特殊字符,所以在使用时也需要对其进行转义,因此就会出现两个反斜线的情况。常用的转义字符如表 2 所示。

表 2 常用转义字符及其含义
转义字符 含 义
\b 匹配一个单词边界,指单词和空格间的位置
\B 匹配非单词边界。如“er\B”,可以匹配“verb”中的“er”,但不能匹配“never” 中的“er”
\d 匹配一个数字字符。它等价于 [0-10]
\D 匹配一个非数字字符。它等价于 [^0-10]
\s 匹配任何空白字符,包括空格、制表符、换页符等。它等价于 [\f\n\r\t\v]
\S 匹配任何非空白字符。它等价于 [^\f\n\r\t\v]
\w 匹配包括下划线的任何单词字符,以及数字字符。它等价于 [a-zA-Z0-10_]
\W 匹配任何非单词字符。它等价于[^A-Za-z0-10_]
\f 匹配一个换页符
\n 匹配一个换行符。就是转到下一行输出
\r 匹配一个回车符。回车和换行不同,回车效果是输出回到本行行首
\t 匹配一个水平制表符。相当于按下键盘的 TAB 键
\v 匹配一个垂直制表符。它的作用是让“\v”后面的字符从下一行开始输出,且开 始的列数为“\v”前一个字符所在列的后面一列

2) 脱字符“^”如果出现在行首之外的位置,正则表达式模式将无法进行匹配。在正则表达式模式中如果只使用了脱字符“^”,那么就不需要使用转义字符进行转义。

3) “$”字符放在文本模式之后来指明数据行必须以该文本模式结尾。

4) 特殊字符点号(.)用来匹配除换行符之外的任意单个字符。它必须匹配一个字符,否则该模式不成立。

5) 在字符后面放置星号(*)表明该字符必须在匹配模式的文本中出现 0 次或多次。

除了以上的元字符之外,还有由普通字符组成的字符集,可以用来匹配特定类型的字符,如表 3 所示。

表 3 字符集及其含义
字符集 含 义
[:alnum:] 匹配任意一个字母或数字,0~10、A~Z 或 a~z
[:alpha:] 匹配任意一个字母,a~z 或 A~Z
[:digit:] 匹配任意一个数字,0~10
[:lower:] 匹配任意一个小写字母,a~z
[:upper:] 匹配任意一个大写字母,A~Z
[:space:] 匹配任意一个空白字符,包括空格、制表符、换行符等
[:blank:] 匹配空格和制表符
[:graph:] 匹配任意一个看得见的可打印字符,不包括空白字符
[:print:] 匹配任意一个可以打印的字符,包括空白字符,但是不包括控制字符、EOF 文件结束符
[:cntrl:] 匹配任意一个控制字符,即 ACSII 字符集中的前 32 个字符,如换行符、制表符等
[:punct:] 匹配任意一个标点符号,如“[]” “{}”等
[:xdigit:] 匹配 16 进制数,即 0~10、a~f 以及 A~F

扩展正则表达式

扩展的正则表达式支持的元字符比标准的正则表达式要多,但扩展的正则表达式对有些标准正则表达式所支持的元字符并不支持,下面主要来学习扩展的正则表达式中新增的元字符。

扩展正则表达式字符及其含义如表 4 所示。

表 4 扩展正则表达式字符及其含义
字 符 含 义
+ 匹配前一个字符出现一次或多次
? 匹配前一个字符出现 0 次或一次
| 匹配逻辑或者,即匹配“|”前或后的字串
0 匹配正则集合
{n,m} 等同于基本正则表达式的 \{n,m\}

加号(+)类似于星号(*)。加号表明前面的字符可以出现 1 次或多次,但必须至少出现 1 次。如果该字符没有出现,那么模式就不会匹配。加号也同样适用于字符组,与星号(*)和问号(?)的使用方法相同。

问号(?)表明前面的字符可以出现 0 次或 1 次,它不会匹配多次出现的字符。如果字符组中的字符出现了 0 次或 1 次,模式匹配就成立;但如果两个字符都出现了,或者其中一个字符出现了 2 次,模式匹配就不成立。

管道符号(|)表示或者同时过滤多个字符。管道符号在检查数据流时,使用逻辑 or 方式指定正则表达式引擎要用的两个或多个模式。如果任何一个模式匹配了数据流文本,文本就通过测试;如果没有模式匹配,则数据流文本匹配失败。

同时管道符号两侧的正则表达式可以采用任何正则表达式模式(包括字符组)来定义文本。

正则表达式模式也可以使用圆括号进行分组。当将正则表达式模式进行分组时,该组会被当作一个标准字符。可以像对普通字符一样给该组使用特殊字符。

扩展正则表达式中的花括号可以为重复的正则表达式指定一个上限。可以使用以下两种方式来指定区间。

grep的高级参数

在前面的章节中我们已经简单地介绍过 grep 命令的概念、常用选项以及 grep 命令支持的几种正则表达式的元字符等内容。那么这里我将会继续介绍 grep 命令的一些高级参数。

grep 命令通过正则表达式来搜索文本,并可以把搜索的结果打印出来。grep 在一个或多个文件中搜索字符串模板,如果模板包括空格,则必须被引用,模板后的所有字符串被看作文件名。搜索的结果被送到屏幕,不影响原文件的内容。

grep 也可用于 Shell 脚本。grep 通过返回一个状态值来说明搜索的状态,如果模板搜索成功,则返回 0;如果搜索不成功,则返回 1;如果搜索的文件不存在,则返回 2。利用这些返回值就可进行一些自动化的文本处理工作。

注意,如果是搜索多个文件,grep 命令的结果只显示在文件中发现匹配模式的文件名;如果搜索的是单一的文件,grep 命令的结果将显示每一个包含匹配模式的行。

grep 命令也支持表 1 中的元字符类型。

【例 1】元字符 ^ 的使用。
创建一个文本文件,读者可以随意命名,这里命令为 text。在 text 文件中写下如下内容。

hello 123456
hello everyone
my name is tom
I am five years old
hello 23654

在终端页面输入如下命令:

[root@bogon ~]# grep ^hello text
hello 123456
hello everyone
hello 23654

脱字符“^”表示匹配以“^”后面字符开头的字符串。“^hello”就表示搜索到 text 文件中以 hello 开头的字符串。

【例 2】搜索字符范围。
创建一个文本文件,读者可以随意命名,这里命令为 text。在 text 文件中写下如下内容:

hello 1234567810
345678
4567810
hello 234567

在终端页面输入如下命令:

[root@bogon ~] # grep [3-8] text
hello 1234567810
345678
4567810
hello 234567

优秀文章