当大叔爱上小萝莉我就爱上了正则表达式
正则表达式的含义
正则表达式是一种文本模式,包括普通字符(例如,a到z之间的字母)和特殊字符(称为"元字符")。模式描述在搜索文本时要匹配的一个或多个字符串。
一、正则表达式基本语法
正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。
例如:
runoo+b,可以匹配runoob、runooob、runoooooob等,+号代表前面的字符必须至少出现一次(1次或多次)。runoo*b,可以匹配runob、runoob、runoooooob等,***** 号代表前面的字符可以不出现,也可以出现一次或者多次(0次、或1次、或多次)。colou?r可以匹配color或者colour,?问号代表前面的字符最多只可以出现一次(0次或1次)。
构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与运算符可以将小的表达式结合在一起来创建更大的表达式。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。
正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为"元字符")组成的文字模式。模式描述在搜索文本时要匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。
元字符
除了普通字符,正则表达式还包括元字符,用于指定更复杂的匹配。正则表达式的元字符包括,其他所有字符均被视为普通字符。少数情况下,反斜线可用于创建元序列,还能转义元字符,使其称为普通字符。
^ $ . [ ] { } - ? * + ( ) | \
很多正则表达式元字符对Shell扩展具有特殊含义,当包含元字符的正则表达式出现在命令行上时,一定要记得将其放入单引号中,避免Shell去扩展这些字符。基本型正则表达式,识别下列元字符。
^ $ . [ ] * 扩展型正则表达式,识别下列元字符
{ } ? + ( ) | 但是,如果使用反斜杠将(、)、{、}转义的话,BRE将其视为元字符;而ERE会将转义后的这些字符视为文字字符。
匹配行首和行尾
使用定位符控制正则表达式在哪个位置上查找匹配项
行首搜索,使用脱字符(^) 示例:^cat行尾搜索,使用美元符号()示例:dog) 示例:dog)示例:dog查找行中唯一的词语,同时使用行首和行尾定位符 示例:^cat$^$,表示行首和行尾之间什么都没有,匹配空行。
往正则表达式中添加通配符
正则表达式使用(.)来匹配除换行符之外的任何单个字符
匹配特定字符,将表达式更改为c[aou]t,匹配以c开头,后面跟着a,o或u,然后是t。使用方括号表达式匹配指定字符集合的单个字符。集合中可以包含任意数量的字符,其中出现的元字符会丢失其特殊含义。但是,有两种特殊情况:脱字符用于表示否定;连字符表示字符范围。
示例:
#1. 方括号表达式中的首个字符是脱字符,剩下的字符则被视为不该在指定字符位置上出现的字符集合。排除型字符集合仍需要指定位置上有一个字符存在,只不过这个字符不能是集合中的字符。[root@ansible tmp]# grep -h '[^bg]'zip dirlist*.txtbunzip2funzipgpg-zipgunzipmzipunzip#2. 匹配以字母或数字开头的所有文件名[root@ansible tmp]# grep -h '^[A-Za-z0-9]'zip dirlist*.txtbzip2bzip2recovergzipmzipbzip2bzip2recovergzipmzip
多选结构
1.单选
[root@ansible tmp]# echo "AAA" | grep 'AAA'AAA
2.二选一
echo "BBB" | grep -E 'AAA|BBB'
echo "BBB" | egrep 'AAA|BBB'
3.多选一
echo "CCC" | egrep 'AAA|BBB|CCC'
echo "CCC" | grep -E 'AAA|BBB|CCC'
4.多选结构与其他正则表达式的组合,匹配文件列表中以bz、gz或zip开头的文件名
grep -Eh '^(bz|gz|zip)' dirlist*.txt
5.上例中去除括号,匹配以bz开头、或者包含gz,或者包含zip的文件名
grep -Eh '^bz|gz|zip' dirlist*.txt
往正则表达式添加倍数
倍数是常与通配符一起使用,倍数应用到正则表达式中的前一位字符。常用的倍数:
星号(**)表示匹配前一表达式的零项或多项。可以在表达式中使用*,而不仅限于字符。示例:c[aou]*t。正则表达式c.*t将匹配cat、coat、culvert乃至ct(c和t之间没有字符)。任何以c开头,后面跟着零个或多个字符,最后以t结尾的数据。
echo "This is a boy." | grep -E '[[:upper:]][[:upper:][:lower:] ]*\.'This is a boy.
{}表示模式中前面字符的期望个数,'c.{2}t’是使用显示倍数的一个示例。该正则表达式将匹配以c开头,后面跟着任意两个字符,最后以t结尾的任何词语。
grep -E '^\(?[0-9]{3}\)? [0-9]{3}-[0-9]{4}$' test
问号(?)表示模式中匹配0次或1次
grep '^\(?[0-9][0-9][0-9]\)? [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]$' test
加号(+)表示模式中匹配1次或多次
grep -E '^([[:alpha:]]+ ?)+$' test1this whata b c
由于正则表达式常含有shell元字符(如$、*和{}),建议练习使用单引号来括起正则表达式。这样可确保字符由命令解释,而不是由shell解释。
grep选项
常用grep选项表
使用find查找路径名
通过正则表达式搜索,找出包含内嵌空格符和其他潜在不规范字符的路径名:
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
使用locate搜索文件
locate程序既支持BRE(–regexp选项),也支持ERE(–regex选项)
locate --regex 'bin/(bz|gz|zip)'
Less和Vim中使用正则表达式搜索文本
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\}$