正则表达式
REGEXP: Regular Expressions,由一类特殊字符及文本字符所编写的模式,其中有些字符(元字符) 不表示字符字面意义,而表示控制或通配的功能,类似于增强版的通配符功能,但与通配符不同,通配符功能是用来处理文件名,而正则表达式是处理文本内容中字符
正则表达式被很多程序和开发语言所广泛支持:vim, less,grep,sed,awk, nginx,mysql 等
正则表达式分两类:
-
基本正则表达式:BRE Basic Regular Expressions
-
扩展正则表达式:ERE Extended Regular Expressions
正则表达式引擎:
采用不同算法,检查处理正则表达式的软件模块,如:PCRE(Perl Compatible Regular
Expressions)
正则表达式的元字符分类:字符匹配、匹配次数、位置锚定、分组
帮助:man 7 regex
1. 基本正则表达式元字符
1.1 字符匹配
字符 | 说明 |
---|---|
. | 匹配任意单个字符,可以是一个汉字 |
[] | 匹配指定范围内的任意单个字符,示例:[song] [0-9] [a-z] [a-zA-Z] |
[^] | 匹配指定范围外的任意单个字符,示例:echo "123song456" |grep -o "[^song]"|xargs |
[:alnum:] | 字母和数字 |
[:alpha:] | 代表任何英文大小写字符,亦即 A-Z, a-z |
[:lower:] | 小写字母,示例:[[:lower:]],相当于[a-z] |
[:upper:] | 大写字母 |
[:blank:] | 空白字符(空格和制表符) |
[:space:] | 包括空格、制表符(水平和垂直)、换行符、回车符等各种类型的空白,比[:blank:]包含的范围广 |
[:cntrl:] | 不可打印的控制字符(退格、删除、警铃…) |
[:digit:] | 十进制数字 |
[:xdigit:] | 十六进制数字 |
[:graph:] | 可打印的非空白字符 |
[:print:] | 可打印字符 |
[:punct:] | 标点符号 |
示例
[root@centos /data]#touch file{A..Z}.txt
[root@centos /data]#touch file{a..z}.txt
[root@centos /data]#ll file[a-d].txt # 通配符处理文件名的结果
-rw-r--r-- 1 root root 0 Mar 31 09:27 fileA.txt
-rw-r--r-- 1 root root 0 Mar 31 09:27 fileB.txt
-rw-r--r-- 1 root root 0 Mar 31 09:27 fileC.txt
-rw-r--r-- 1 root root 0 Mar 31 09:28 filea.txt
-rw-r--r-- 1 root root 0 Mar 31 09:28 fileb.txt
-rw-r--r-- 1 root root 0 Mar 31 09:28 filec.txt
-rw-r--r-- 1 root root 0 Mar 31 09:28 filed.txt
[root@centos /data]#ll |grep "file[a-d].txt" # 正侧表达式处理文本内容中字符的结果
-rw-r--r-- 1 root root 0 Mar 31 09:28 filea.txt
-rw-r--r-- 1 root root 0 Mar 31 09:28 fileb.txt
-rw-r--r-- 1 root root 0 Mar 31 09:28 filec.txt
-rw-r--r-- 1 root root 0 Mar 31 09:28 filed.txt
[root@centos /data]#
示例
[root@centos ~]#ls /etc/ | grep 'rc[0-6]'
rc0.d
rc1.d
rc2.d
rc3.d
rc4.d
rc5.d
rc6.d
[root@centos ~]#ls /etc/ | grep 'rc[.0-6]' # 结果中 rc. rc0 rc1 等都符合
rc.d
rc.local
rc0.d
rc1.d
rc2.d
rc3.d
rc4.d
rc5.d
rc6.d
[root@centos ~]#ls /etc/ | grep 'rc[.0-6].' # 最后一个 . 表示任意一个字符
rc.d
rc.local
rc0.d
rc1.d
rc2.d
rc3.d
rc4.d
rc5.d
rc6.d
[root@centos ~]#ls /etc/ | grep 'rc[.0-6]\.' # \. 表示点号
rc0.d
rc1.d
rc2.d
rc3.d
rc4.d
rc5.d
rc6.d
[root@centos ~]#
1.2 匹配次数
用在要指定次数的字符后面,用于指定前面的字符要出现的次数
字符 | 说明 |
---|---|
* | 匹配前面的字符任意次,包括0次,贪婪模式:尽可能长的匹配 |
.* | 任意长度的任意字符 |
\? | 匹配其前面的字符0或1次,即:可有可无,懒惰模式 |
\+ | 匹配其前面的字符至少1次,即:肯定有,>=1次 |
\{n\} | 匹配前面的字符n次 |
\{m,n\} | 匹配前面的字符至少m次,至多n次 |
\{,n\} | 匹配前面的字符至多n次,<=n |
\{n,\} | 匹配前面的字符至少n次 |
示例
[root@centos ~]#cat test.txt
google
goooooooooooooooooogle
ggle
gogle
gooooOOOOO00000gle
gooogle
[root@centos ~]#grep 'go\{2,\}gle' test.txt # 匹配 o 至少 2 次
google
goooooooooooooooooogle
gooogle
[root@centos ~]#grep 'goo\+gle' test.txt # 匹配 o 至少 1 次
google
goooooooooooooooooogle
gooogle
[root@centos ~]#grep 'goo*gle' test.txt # 匹配 o 任意次,贪婪匹配
google
goooooooooooooooooogle
gogle
gooogle
[root@centos ~]#grep 'gooo*gle' test.txt # 匹配 o 任意次,贪婪匹配
google
goooooooooooooooooogle
gooogle
[root@centos ~]#
示例:匹配正负数
[root@centos ~]#echo -1 -2 123 -123 234 | grep '[0-9]'
-1 -2 123 -123 234
[root@centos ~]#echo -1 -2 123 -123 234 | grep '\-\?[0-9]\+'
-1 -2 123 -123 234
[root@centos ~]#echo -1 -2 123 -123 234 | grep -E '\-?[0-9]+'
-1 -2 123 -123 234
[root@centos ~]#echo -1 -2 123 -123 234 | grep -E -- '-?[0-9]+'
-1 -2 123 -123 234
[root@centos ~]#echo -1 -2 123 -123 234 | grep -E '(-)?[0-9]+'
-1 -2 123 -123 234
[root@centos ~]#
1.3 位置锚定
位置锚定可以用于定位出现的位置
字符 | 说明 |
---|---|
^ | 行首锚定,用于模式的最左侧 |
$ | 行尾锚定,用于模式的最右侧 |
^PATTERN$ | 用于模式匹配整行 |
^$ | 空行 |
^[[:space:]]*$ | 空白行 |
\< 或 \b | 词首锚定,用于单词模式的左侧 |
\> 或 \b | 词尾锚定,用于单词模式的右侧 |
\<PATTERN\> | 匹配整个单词 |
\w | 匹配单词构成部分,等价于[_[:alnum:]] |
\W | 匹配非单词构成部分,等价于[^_[:alnum:]] |
\S | 匹配任何非空白字符。等价于 [^ \f\n\r\t\v] |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。 注意 Unicode 正则表达式会匹配全角空格符 |
注意: 单词是由字母,数字,下划线组成
示例:排除空行和 # 号开头的行
[root@centos ~]#grep -Ev '^#|^$' /etc/fstab
UUID=a15bf413-4fc3-4be0-b030-6ec57dd3a654 / xfs defaults 0 0
UUID=be471bb4-fd37-4a47-82d1-6dbc74672ae9 /boot ext4 defaults 1 2
UUID=8b2d98d6-68d2-48c7-acea-32045758a40b /data xfs defaults 0 0
UUID=27a455ce-2ca9-429a-ad3a-5a9e36afb869 swap swap defaults 0 0
[root@centos ~]#grep '^[^$#]' /etc/fstab
UUID=a15bf413-4fc3-4be0-b030-6ec57dd3a654 / xfs defaults 0 0
UUID=be471bb4-fd37-4a47-82d1-6dbc74672ae9 /boot ext4 defaults 1 2
UUID=8b2d98d6-68d2-48c7-acea-32045758a40b /data xfs defaults 0 0
UUID=27a455ce-2ca9-429a-ad3a-5a9e36afb869 swap swap defaults 0 0
# ^ 行首锚定,用于模式的最左侧
# [^] 匹配指定范围外的任意单个字符
[root@centos ~]#grep '^[^#]' /etc/fstab # ^[^#] 匹配行首除井号(#)号之外的任意单个字符,即去除井号(#)号注释
UUID=a15bf413-4fc3-4be0-b030-6ec57dd3a654 / xfs defaults 0 0
UUID=be471bb4-fd37-4a47-82d1-6dbc74672ae9 /boot ext4 defaults 1 2
UUID=8b2d98d6-68d2-48c7-acea-32045758a40b /data xfs defaults 0 0
UUID=27a455ce-2ca9-429a-ad3a-5a9e36afb869 swap swap defaults 0 0
[root@centos ~]#
1.4 分组其他
1.4.1 分组
分组:() 将多个字符捆绑在一起,当作一个整体处理,如:\(root\)+
# abc 出现三次
[root@centos ~]#echo abcabcabc | grep -E "(abc){3}"
abcabcabc
[root@centos ~]#echo abcabcabc | grep "\(abc\)\{3\}"
abcabcabc
[root@centos ~]#
后向引用:分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名 方式为: \1
, \2
, \3
, …
\1
表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符
示例
\(string1\(string2\)\)
\1 表示 string1\(string2\)
\2 表示 string2
注意: 后向引用
引用前面的分组括号中的模式所匹配字符,而非模式本身
1.4.2 或者
或者:\|
示例
a \| b # a 或者 b
C \| cat # C 或者 cat
\(C\|c\)at # Cat 或者 cat
# 1abc 或 2abc
[root@centos ~]#echo 1abc | grep "\(1\|2\)abc"
1abc
[root@centos ~]#
示例:排除空行和 # 开头的行
[root@centos ~]#grep -Ev "^#|^$" /etc/fstab
UUID=a15bf413-4fc3-4be0-b030-6ec57dd3a654 / xfs defaults 0 0
UUID=be471bb4-fd37-4a47-82d1-6dbc74672ae9 /boot ext4 defaults 1 2
UUID=8b2d98d6-68d2-48c7-acea-32045758a40b /data xfs defaults 0 0
UUID=27a455ce-2ca9-429a-ad3a-5a9e36afb869 swap swap defaults 0 0
[root@centos ~]#grep -v '^#\|^$' /etc/fstab
UUID=a15bf413-4fc3-4be0-b030-6ec57dd3a654 / xfs defaults 0 0
UUID=be471bb4-fd37-4a47-82d1-6dbc74672ae9 /boot ext4 defaults 1 2
UUID=8b2d98d6-68d2-48c7-acea-32045758a40b /data xfs defaults 0 0
UUID=27a455ce-2ca9-429a-ad3a-5a9e36afb869 swap swap defaults 0 0
[root@centos ~]#grep -v '^\(#\|$\)' /etc/fstab
UUID=a15bf413-4fc3-4be0-b030-6ec57dd3a654 / xfs defaults 0 0
UUID=be471bb4-fd37-4a47-82d1-6dbc74672ae9 /boot ext4 defaults 1 2
UUID=8b2d98d6-68d2-48c7-acea-32045758a40b /data xfs defaults 0 0
UUID=27a455ce-2ca9-429a-ad3a-5a9e36afb869 swap swap defaults 0 0
[root@centos ~]#grep "^[^#]" /etc/fstab
UUID=a15bf413-4fc3-4be0-b030-6ec57dd3a654 / xfs defaults 0 0
UUID=be471bb4-fd37-4a47-82d1-6dbc74672ae9 /boot ext4 defaults 1 2
UUID=8b2d98d6-68d2-48c7-acea-32045758a40b /data xfs defaults 0 0
UUID=27a455ce-2ca9-429a-ad3a-5a9e36afb869 swap swap defaults 0 0
[root@centos ~]#
2 扩展正则表达式元字符
2.1 字符匹配
字符 | 说明 |
---|---|
. | 任意单个字符 |
[song] | 指定范围的字符,例:手机号\<1[3456789][0-9]{9}\> |
[^song] | 不在指定范围的字符 |
[:alnum:] | 字母和数字 |
[:alpha:] | 代表任何英文大小写字符,亦即 A-Z, a-z |
[:lower:] | 小写字母,示例:[[:lower:]],相当于[a-z] |
[:upper:] | 大写字母 |
[:blank:] | 空白字符(空格和制表符) |
[:space:] | 水平和垂直的空白字符(比[:blank:]包含的范围广) |
[:cntrl:] | 不可打印的控制字符(退格、删除、警铃…) |
[:digit:] | 十进制数字 |
[:xdigit:] | 十六进制数字 |
[:graph:] | 可打印的非空白字符 |
[:print:] | 可打印字符 |
[:punct:] | 标点符号 |
2.2 次数匹配
字符 | 说明 |
---|---|
* | 匹配前面字符任意次 |
? | 0或1次 |
+ | 1次或多次 |
{n} | 匹配n次 |
{m,n} | 至少m,至多n次 |
2.3 位置锚定
字符 | 说明 |
---|---|
^ | 行首 |
$ | 行尾 |
\<, \b | 词首 |
\>, \b | 词尾 |
2.4 分组其他
字符 | 说明 |
---|---|
() | 分组 |
\1, \2, ... | 反向引用 |
| | 或者 |
a|b | a 或 b |
C|cat | C 或 cat |
(C|c)at | Cat 或 cat |