正则表达式又称正规表达式、常规表达式。在代码中常简写为 regex、regexp 或 RE。正则表达式是使用单个字符串来描述、匹配一系列符合某个句法规则的字符串,简单来说, 是一种匹配字符串的方法,通过一些特殊符号,实现快速查找、删除、替换某个特定字符串。
正则表达式是由普通字符与元字符组成的文字模式。模式用于描述在搜索文本时要匹 配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进 行匹配。其中普通字符包括大小写字母、数字、标点符号及一些其他符号,元字符则是指 那些在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符 前面的字符)在目标对象中的出现模式。
正则表达式一般用于脚本编程与文本编辑器中。很多文本处理器与程序设计语言均支持正则表达式,例如 Linux 系统中常见的文本处理器(grep、egrep、sed、awk)以及应用比较广泛的 Python 语言。正则表达式具备很强大的文本匹配功能,能够在文本海洋中快速高效地处理文本。
对于一般计算机用户来说,由于使用到正则表达式的机会不多,所以无法体会正则表达 式的魅力,而对于系统管理员来说,正则表达式则是必备技能之一。
正则表达式对于系统管理员来说是非常重要的,系统运行过程中会产生大量的信息,这些信息有些是非常重要的,有些则仅是告知的信息。身为系统管理员如果直接看这么多的信息数据,无法快速定位到重要的信息,如“用户账号登录失败”“服务启动失败”等信息。这时可以通过正则表达式快速提取“有问题”的信息。如此一来,可以将运维工作变得更加简单、 方便。
目前很多软件也支持正则表达式,最常见的就是邮件服务器。在 Internet 中,垃圾/广告邮件经常会造成网络塞车,如果在服务器端就将这些问题邮件提前剔除的话,客户端就会 减少很多不必要的带宽消耗。而目前常用的邮件服务器 postfix 以及支持邮件服务器的相关分析软件都支持正则表达式的对比功能。将来信的标题、内容与特殊字符串进行对比,发现 问题邮件就过滤掉。
除邮件服务器之外,很多服务器软件都支持正则表达式。虽然这些软件都支持正则表达 式,不过字符串的对比规则还需要系统管理员来添加,因此正则表达式是系统管理员必须掌 握的技能之一。
正则表达式的字符串表达方法根据不同的严谨程度与功能分为基本正则表达式与扩展正则表达式。基础正则表达式是常用正则表达式最基础的部分。在 Linux 系统中常见的文件处理工具中 grep 与 sed 支持基础正则表达式,而 egrep 与 awk 支持扩展正则表达式。掌握基础正则表达式的使用方法,首先必须了解基本正则表达式所包含元字符的含义,下面通过grep 命令以举例的方式逐个介绍。
下面的操作需要提前准备一个名为 test.txt 的测试文件,文件具体内容如下所示。
[root@localhost ~]# cat test.txt
cat test.t
[root@localhost ~]# grep -n ‘the’ test.txt
[root@localhost ~]# grep -in ‘the’ test.txt
若反向选择,如查找不包含“the”字符的行,则需要通过 grep 命令的“-v”选项实现,并配合“-n”一起使用显示行号。
grep -vn ‘the’ test.txt
想要查找“shirt”与“short”这两个字符串时,可以发现这两个字符串均包含“sh”与“rt”。此时执行以下命令即可同时查找到“shirt”与“short”这两个字符串,其中“[]”中无论有几个字符, 都仅代表一个字符,也就是说“[io]”表示匹配“i”或者“o”。
如:**[root@localhost ~]#grep -n ‘sh[io]rt’ test.txt **意思就是 找出语句中带有 shirt 或者 short 的句子
1:he was short and fat.
2:He was wearing a blue polo shirt with black pants.
若要查找包含重复单个字符“oo”时,只需要执行以下命令即可。
[root@localhost ~]# grep -n ‘oo’ test.txt
这样就可以找出包含重复单oo字符的语句
3:The home of Football on BBC Sport online.
5:google is the best tools for search keyword.
8:a wood cross!
11:#woood #
12:#woooooood #
14:I bet this place is really spooky late at night!
若查找“oo”前面不是“w”的字符串,只需要通过集合字符的反向选择“[^]”来实现该目的。例如执行“grep -n‘[^w]oo’test.txt”命令表示在 test.txt 文本中查找“oo”前面不是“w”的字符串。
[root@localhost ~]# grep -n ‘【^w】oo’ test.txt
在上述命令的执行结果中发现“woood”与“wooooood”也符合匹配规则,二者均包含“w”。其实通过执行结果就可以看出,符合匹配标准的字符加粗显示,而上述结果中可以得知, “#woood #”中加粗显示的是“ooo”,而“oo”前面的“o”是符合匹配规则的。同理“#woooooood #”也符合匹配规则。
若不希望“oo”前面存在小写字母,可以使用“grep -n‘[^a-z]oo’test.txt”命令实现,其中
“a-z”表示小写字母,大写字母则通过“A-Z”表示。
[root@localhost ~]# grep -n ‘【^a-z】oo’ test.txt
查找包含数字的行可以通过“grep -n‘[0-9]’test.txt”命令来实现。
[root@localhost ~]# grep -n ‘[0-9]’ test.txt
基础正则表达式包含两个定位元字符:“^”(行首)与“$”(行尾)。在上面的示例中, 查询“the”字符串时出现了很多包含“the”的行,如果想要查询以“the”字符串为行首的行,则可以通过“^”元字符来实现。
[root@localhost ~]# grep -n ‘^the’ test.txt
查询以小写字母开头的行可以通过“^【a-z】”规则来过滤,查询大写字母开头的行则使用
“【A-Z】”规则,若查询不以字母开头的行则使用“【^a-zA-Z】”规则。
[root@localhost ~]# grep -n `^【a-z】'test.txt
[root@localhost ~]# grep -n `^【A-Z】'test.txt
[root@localhost ~]# grep -n ‘【a-zA-Z】’ test.txt
“^”符号在元字符集合“[]”符号内外的作用是不一样的,在“[]”符号内表示反向选择,在“[]” 符号外则代表定位行首。反之,若想查找以某一特定字符结尾的行则可以使用“$”定位符。例如,执行以下命令即可实现查询以小数点(.)结尾的行。因为小数点(.)在正则表达式中也是一个元字符(后面会讲到),所以在这里需要用转义字符“\”将具有特殊意义的字符转化成普通字符。
[root@localhost ~]# grep -n ‘.$’ test.txt
当查询空白行时,执行“grep -n‘^$’test.txt”命令即可。
[root@localhost ~]# grep -n ‘^$’ test.txt
前面提到,在正则表达式中小数点(.)也是一个元字符,代表任意一个字符。例如执行以下命令就可以查找“w??d”的字符串,即共有四个字符,以 w 开头 d 结尾。
[root@localhost ~]# grep -n ‘w…d’ test.txt
在上述结果中,“wood”字符串“w…d”匹配规则。若想要查询 oo、ooo、ooooo 等资料, 则需要使用星号()元字符。但需要注意的是,“”代表的是重复零个或多个前面的单字符。 “o*”表示拥有零个(即为空字符)或大于等于一个“o”的字符,因为允许空字符,所以执行“grep
-n ‘o*’ test.txt”命令会将文本中所有的内容都输出打印。如果是“oo*”,则第一个 o 必须存在, 第二个 o 则是零个或多个 o,所以凡是包含 o、oo、ooo、ooo,等的资料都符合标准。同理,若查询包含至少两个 o 以上的字符串,则执行“grep -n ‘ooo*’ test.txt”命令即可。
[root@localhost ~]# grep -n 'ooo’ test.txt*
3:The home of Football on BBC Sport online.
5:google is the best tools for search keyword.
8:a wood cross!
11:#woood #
12:#woooooood #
14:I bet this place is really spooky late at night!
查询以 w 开头 d 结尾,中间包含至少一个 o 的字符串,执行以下命令即可实现。
[root@localhost ~]# grep -n ‘woo*d’ test.txt
8:a wood cross!
11:#woood #
12:#woooooood #
执行以下命令即可查询任意数字所在行
[root@localhost ~]# grep -n ‘[0-9]【0-9】*’ test.txt
在上面的示例中,使用了“.”与“*”来设定零个到无限多个重复的字符,如果想要限制一个范围内的重复的字符串该如何实现呢?例如,查找三到五个 o 的连续字符,这个时候就需要使用基础正则表达式中的限定范围的字符“{}”。因为“{}”在 Shell 中具有特殊意义,所以在使用“{}”字符时,需要利用转义字符“\”,将“{}”字符转换成普通字符。“{}”字符的使用方法如下所示。
① 查询两个 o 的字符。
[root@localhost ~]# grep -n ‘o{2}’ test.txt
② 查询以 w 开头以 d 结尾,中间包含 2~5 个 o 的字符串。
[root@localhost ~]# grep -n ‘wo{2,5}d’ test.txt
③ 查询以 w 开头以 d 结尾,中间包含 2 个或 2 个以上 o 的字符串。
[root@localhost ~]# grep -n ‘wo{2,}d’ test.txt
通过上面几个简单的示例,可以了解到常见的基础正则表达式的元字符主要包括以下几 个,如表 4-1 所示。
-a 或 --text : 不要忽略二进制的数据。
-A<显示行数> 或 --after-context=<显示行数> : 除了显示符合范本样式的那一列之外,并显示该行之后的内容。
-b 或 --byte-offset : 在显示符合样式的那一行之前,标示出该行第一个字符的编号。
-B<显示行数> 或 --before-context=<显示行数> : 除了显示符合样式的那一行之外,并显示该行之前的内容。
-c 或 --count : 计算符合样式的列数。
-C<显示行数> 或 --context=<显示行数>或-<显示行数> : 除了显示符合样式的那一行之外,并显示该行之前后的内容。
-d <动作> 或 --directories=<动作> : 当指定要查找的是目录而非文件时,必须使用这项参数,否则grep指令将回报信息并停止动作。
-e<范本样式> 或 --regexp=<范本样式> : 指定字符串做为查找文件内容的样式。
-E 或 --extended-regexp : 将样式为延伸的正则表达式来使用。
-f<规则文件> 或 --file=<规则文件> : 指定规则文件,其内容含有一个或多个规则样式,让grep查找符合规则条件的文件内容,格式为每行一个规则样式。
-F 或 --fixed-regexp : 将样式视为固定字符串的列表。
-G 或 --basic-regexp : 将样式视为普通的表示法来使用。
-h 或 --no-filename : 在显示符合样式的那一行之前,不标示该行所属的文件名称。
-H 或 --with-filename : 在显示符合样式的那一行之前,表示该行所属的文件名称。
-i 或 --ignore-case : 忽略字符大小写的差别。
-l 或 --file-with-matches : 列出文件内容符合指定的样式的文件名称。
-L 或 --files-without-match : 列出文件内容不符合指定的样式的文件名称。
-n 或 --line-number : 在显示符合样式的那一行之前,标示出该行的列数编号。
-o 或 --only-matching : 只显示匹配PATTERN 部分。
-q 或 --quiet或–silent : 不显示任何信息。
-r 或 --recursive : 此参数的效果和指定"-d recurse"参数相同。
-s 或 --no-messages : 不显示错误信息。
-v 或 --revert-match : 显示不包含匹配文本的所有行。
-V 或 --version : 显示版本信息。
-w 或 --word-regexp : 只显示全字符合的列。
-x --line-regexp : 只显示全列符合的列。
-y : 此参数的效果和指定"-i"参数相同
基本上grep已经够用了……
egrep有时候比grep好用,有时候比grep难用
grep仅支持基础正则表达式,egrep支持拓展正则表达式