1. 什么是正则表达式
简单的说,正则表达式是一种用于识别文本模式的符号表示法。grep的基本功能是在文本文件中搜索与指定的正则表达式匹配的文本。
1.1 元字符
除了普通字符,正则表达式还包括元字符,用于指定更复杂的匹配。正则表达式的元字符包括,其他所有字符均被视为普通字符。少数情况下,反斜线可用于创建元序列,还能转义元字符,使其称为普通字符。
^ $ . [ ] { } - ? * + ( ) | \
很多正则表达式元字符对Shell扩展具有特殊含义,当包含元字符的正则表达式出现在命令行上时,一定要记得将其放入单引号中,避免Shell去扩展这些字符。
BRE(Basic Regular Expression)基本型正则表达式,识别下列元字符
^ $ . [ ] *
ERE(Extended Regular Expression)扩展型正则表达式,识别下列元字符
{ } ? + ( ) |
但是,如果使用反斜杠将(、)、{、}转义的话,BRE将其视为元字符;而ERE会将转义后的这些字符视为文字字符。
1.2 匹配行首和行尾
使用定位符控制正则表达式在哪个位置上查找匹配项
- 行首搜索,使用脱字符(^) 示例:^cat
- 行尾搜索,使用美元符号($) 示例:dog$
- 查找行中唯一的词语,同时使用行首和行尾定位符 示例:^cat$
- ^$,表示行首和行尾之间什么都没有,匹配空行。
1.3 向正则表达式添加通配符
- 正则表达式使用(.)来匹配除换行符之外的任何单个字符
- 匹配特定字符,将表达式更改为c[aou]t,匹配以c开头,后面跟着a,o或u,然后是t。使用方括号表达式匹配指定字符集合的单个字符。集合中可以包含任意数量的字符,其中出现的元字符会丢失其特殊含义。但是,有两种特殊情况:脱字符用于表示否定;连字符表示字符范围。
示例:
#1. 方括号表达式中的首个字符是脱字符,剩下的字符则被视为不该在指定字符位置上出现的字符集合。排除型字符集合仍需要指定位置上有一个字符存在,只不过这个字符不能是集合中的字符。
[root@ansible tmp]# grep -h '[^bg]'zip dirlist*.txt
bunzip2
funzip
gpg-zip
gunzip
mzip
unzip
#2. 匹配以字母或数字开头的所有文件名
[root@ansible tmp]# grep -h '^[A-Za-z0-9]'zip dirlist*.txt
bzip2
bzip2recover
gzip
mzip
bzip2
bzip2recover
gzip
mzip
1.4 多选结构
- 单选
[root@ansible tmp]# echo "AAA" | grep 'AAA'
AAA
- 二选一
[root@ansible tmp]# echo "BBB" | grep -E 'AAA|BBB'
BBB
[root@ansible tmp]# echo "BBB" | egrep 'AAA|BBB'
BBB
- 多选一
[root@ansible tmp]# echo "CCC" | egrep 'AAA|BBB|CCC'
CCC
[root@ansible tmp]# echo "CCC" | grep -E 'AAA|BBB|CCC'
CCC
4.多选结构与其他正则表达式的组合,匹配文件列表中以bz、gz或zip开头的文件名
[root@ansible tmp]# grep -Eh '^(bz|gz|zip)' dirlist*.txt
5.上例中去除括号,匹配以bz开头、或者包含gz,或者包含zip的文件名
[root@ansible tmp]# grep -Eh '^bz|gz|zip' dirlist*.txt
1.5 向正则表达式添加倍数
倍数是常与通配符一起使用,倍数应用到正则表达式中的前一位字符。常用的倍数:
- 星号(*)表示匹配前一表达式的零项或多项。可以在表达式中使用*,而不仅限于字符。示例:c[aou]*t。正则表达式c.*t将匹配cat、coat、culvert乃至ct(c和t之间没有字符)。任何以c开头,后面跟着零个或多个字符,最后以t结尾的数据。
#判断字符串是否是一句话,该字符串以大写开头,然后是任意多个大/小写字母和空格符 [root@ansible tmp]# echo "This is a boy." | grep -E '[[:upper:]][[:upper:][:lower:] ]*\.' This is a boy.
- {}表示模式中前面字符的期望个数,'c.{2}t’是使用显示倍数的一个示例。该正则表达式将匹配以c开头,后面跟着任意两个字符,最后以t结尾的任何词语。
#匹配两种类型的电话号码(nnn) nnn-nnnn和nnn nnn-nnnn [root@ansible tmp]# grep -E '^\(?[0-9]{3}\)? [0-9]{3}-[0-9]{4}$' test
- 问号(?)表示模式中匹配0次或1次
#匹配两种类型的电话号码(nnn) nnn-nnnn和nnn nnn-nnnn grep '^\(?[0-9][0-9][0-9]\)? [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]$' test
- 加号(+)表示模式中匹配1次或多次
#匹配单个空格符分割的一个或多个字母 [root@ansible tmp]# grep -E '^([[:alpha:]]+ ?)+$' test1 this what a b c
由于正则表达式常含有shell元字符(如$、*和{}),建议练习使用单引号来括起正则表达式。这样可确保字符由命令解释,而不是由shell解释。
正则表达式
选项 | 描述 |
---|---|
. | 句点(.)匹配任何单个字符 |
? | 前面的项目是可选的,且最多匹配一次 |
* | 前面的项目将匹配零次或多次 |
+ | 前面的项目将匹配一次或多次 |
{n} | 前面的项目恰好匹配n次 |
{n,} | 前面的项目恰好匹配n次或更多次 |
{,m} | 前面的项目最多匹配m次。 |
{n,m} | 前面的项目至少匹配n次,但不超过m次。 |
[:almum:] | 字母数字字符,等同于[0-9A-Za-z] |
[:alpha:] | 字母字符,等同于[A-Za-z] |
[:blank:] | 空白字符:空格和制表符 |
[:cntrl:] | 控制字符 |
[:digit:] | 数字:0-9 |
[:graph:] | 图形字符 |
[:lower:] | 小写字母 |
[:print:] | 可打印字符:[:almum:]、[:punct:]和空格 |
[:punct:] | 标点符号 |
[:space:] | 空格字符;制表符、换行符、垂直制表符、换页符、回车符和空格 |
[:upper:] | 大写字母 |
[:xdigit:] | 十六进制数字 |
\b | 匹配词语两侧的空字符串 |
\B | 匹配词语中间的空字符串 |
< | 匹配词语开头的空字符串 |
> | 匹配词语末尾的空字符串 |
\w | 匹配词语组分 |
\W | 匹配非词语组分 |
\s | 匹配空格 |
\S | 匹配非空格 |
1.6 grep选项
常用grep选项表
选项 | 功能 |
---|---|
-i | 不区分大小写 |
-v | 反向匹配,仅显示不包含正则表达式匹配项的行 |
-r | 将递归地将匹配正则表达式的数据搜索应用到一组文件或目录 |
-A NUMBER | 显示正则表达式匹配项之后的行数 |
-B NUMBER | 显示正则表达式匹配项之前的行数 |
-e | 使用-e选项,可以提供多个正则表达式,并将与逻辑或一起使用 |
-c | 输出匹配数量 |
-l | 输出包含匹配项的文件名,不再输出文本行。 |
-L | 和-l选项类似,但是只输出不包含匹配项的文件名 |
-n | 在包含匹配项的文本行前加上行号 |
-h | 在多文件搜索中禁止输出文件名 |
grep还有很多其他选项,使用man page可以对它们进行研究。
1.7 使用find查找路径名
通过正则表达式搜索,找出包含内嵌空格符和其他潜在不规范字符的路径名:
[root@ansible tmp]# find . -regex '.*[^-_./0-9a-zA-Z].*'
./etc/systemd/system/getty.target.wants/getty@tty1.service
./etc/systemd/system/dev-virtio\x2dports-org.qemu.guest_agent.0.device.wants
1.8 使用locate搜索文件
locate程序既支持BRE(–regexp选项),也支持ERE(–regex选项)
[root@ansible tmp]# locate --regex 'bin/(bz|gz|zip)'
1.9 Less和Vim中使用正则表达式搜索文本
- Less支持ERE和BRE
[root@ansible tmp]# less phonelist.txt
(538) 794-599
(455) 199-8136
(853) 247-1873
(261) 191-8873
(296) 691-0723
(158) 594-7899
(292) 892-0199
(518) 473-8491
(948) 389-0795
(846) 249-8228
(931) 979-6425
(481) 802-3580
(378) 694-1509
(333) 991-736
#执行less命令后,先输入斜杠,然后输入正则表达式进行匹配
/^\([0-9]{3}\) [0-9]{3}-[0-9]{4}$
- Vim只支持BRE,因此上述的正则表达式得改写成这样
/([0-9]\{3\}) [0-9]\{3\}-[0-9]\{4\}$
更多推荐
Linux正则表达式
发布评论