1 、什么是正则表达式
正则表达式是通过一些特殊字符的排列,用以查找、替换、删除一行或多行文字字符串,简单的说,正则表达式就是用在字符串的处理上面的一项表示式。由于正则表达式语法简练,功能强大,得到了许多
程序设计语言的支持,包括Java、C++、Perl以及Shell等。
为什么使用正则表达式
在进行程序设计的过程中,用户会不可避免地遇到处理某些文本的情况。有的时候,用户还需要查找符
合某些比较复杂规则的字符串。对于这些情况,如果单纯依靠程序设计语言本身,则往往会使得用户通
过复杂的代码来实现。但是,如果使用正则表达式,则会以非常简短的代码来完成。
如何学习正则表达式
- 重点在于理解元字符
- 掌握好正则表达式的语法
- 开拓思路,寻找最佳的表达方法
如何使用正则表达式
当一个正则表达式完成之后,并能够保证这个表达式一定是准确的,需要不断地测试才可以确定其正确
与否。在不同的环境下,用户需要不同的工具来帮助他完成测试的过程。如果是在Shell命令行中,用户
可以使用grep命令来测试。
grep命令
grep家族有三大成员分别为:
grep:支持使用基本正则表达式。
egrep:支持使用扩展正则表达式。
fgrep:不支持使用正则表达式,即所有的正则表达式中的元字符都将作为一般字符,仅仅拥有其字面意义,不再拥有特殊意义。
grep命令的名称来自于全局搜索正则表达式并打印文本行(Global Search Regular Expression and
Print out the line)的缩写。它是一个非常古老的UNIX命令,也是一种强大的文本搜索工具。grep命令
基本正则表达式
^: 代表。。。的开始
abcabcbcd -> 要以abc开始字符串-> ^abc
bcdabcabc -> 就不是以abc开始字符串
从字符串的开始进行匹配
[root@whl grep]# echo 'abcdabcdabcd' | grep '^abcd'
abcd abcdabcd
$: 代表…的结束
abcabcbcd ->以bcd结尾的字符串 -> bcd$
bcdabcabc -> 不是以bcd结尾的字符串
[root@whl grep]# echo 'abcdabcdabcd' | grep 'abcd$'
abcdabcdab
cd
.: 任意的单个字符: . -> a, b, A, C, 1, ?, *, 都是任意的单个字符,
.hello.匹配hello.前后任意的两个字符
[root@whl grep]# echo -e 'hello
xhelloxxxxx
xxxhelloxxxx
XXXXXXXXXXxxxxxhelloxxxxxx' | grep '.hello.'
xhelloxxxxx
xxxhelloxxxx
XXXXXXXXXXxxxxxhelloxxxxxx
、* 代表的是*之前的正则表达式重复0次或任意多次
a* -> aaa, aaaaaa, aaaaaaaaaaaaaaaaaaaaa...
a* -> ""
[root@whl grep]# echo 'abcdabcdabcd' | grep 'abcd*'
abcdabcdabcd
[str]-> [abc] ->中括号的意思是字符集:[abc] -> 匹配单个字符:字符可以是a, 也可是b, 也可以是c
a, b, c
[root@whl grep]# echo -e 'ahello\nbhello\nchello\nzhello\nxhello' | grep '[abc]hello'
ahello
bhello
chello
[^str] -> [^abc] -> 取的是abc的补集, 除了abc之外字符
[root@whl grep]# echo -e 'ahello\nbhello\nchello\nzhello\nxhello' | grep '[^abc]hello'
zhello
xhello
[a-b]: 代表字符集, 也是单个字符,但是单个字符可以是a-b之间的任意字符
[0-9], [a-z], [A-Z], 使用a和b之间必须是连续的0
[root@whl grep]# echo -e 'ahello\nbhello\nchello\nzhello\nxhello' | grep '[a-z]hello'
ahello
bhello
chello
zhello
xhello
.*: 匹配任务的字符:重复0次或任意多次
[root@whl ~]# printf "xxxxxhelloxxx\njjjjjjhellojjjjj\nhffffhellofssss\nafffffhelloxxxx\n" | grep '.*hello.*'
xxxxxhelloxxx
jjjjjjhellojjjjj
hffffhellofssss
afffffhelloxxxx
[root@whl ~]# printf 'helloasdasdas\n'
helloasdasdas
[root@whl ~]# printf 'helloasdasdas\n' | grep '.*hello.*'
helloasdasdas
扩展正则表达式
后面使用的形式:就是不直接使用grep 而使用grep -E或者grep -P
{n,m} 匹配n到m次,前一个字符。指的是重复的上限和下限:重复n到m次,尽可能多的重复
aaaaaaaaa -> a{5,8} -> aaaaaaaa
root@whl ~]# echo "aaaaaaaaaa" | grep -E 'a{5,8}'
aaaaaaaaaa
[root@whl ~]# echo "aaaaaaaaa" | grep -E 'a{5,8}'
aaaaaaaaa
[root@whl ~]# echo "aaaaab" | grep -E 'a{5,8}'
aaaaab
[root@whl ~]# echo "aaaaaab" | grep -E 'a{5,8}'
aaaaaab
{n} n次,指定是{n}正则表达式重复指定次数n次
[root@whl ~]# echo "aaaaaa" | grep -E 'a{5}'
aaaaaa
[root@whl ~]# echo "aaaaaa" | grep -Eo 'a{5}'
aaaaa
[root@whl ~]# echo "aaaaaa" | grep -Po 'a{5}'
aaaaa
{n,} 至少N次,多了不限。只指定了下限(不足N个匹配不到)
[root@whl ~]# echo "aaaa" | grep -E 'a{5,}'
[root@whl ~]# echo "aaaaaaaaa" | grep -E 'a{5,}'
aaaaaaaaa
{,m} 至多m次,只指定了上限
[root@whl ~]# echo "aaaa" | grep -Eo 'a{,7}'
aaaa
[root@whl ~]# echo "aaaaaaaaaaa" | grep -Eo 'a{,7}'
aaaaaaa
aaaa
先匹配7个a再匹配4个a
注意:grep要将{}转义,\{\},egrep不需要转义
[root@whl ~]# echo "aaaa" | grep '{4}'
[root@whl ~]# echo "aaaa" | grep 'a\{4,\}'
aaaa
12)(),定义子表达式的开始和结束位置。例如,正则表达式“(love).*\1”表示匹配2个“love”中间包含任意个字符的文本行,其中“\1”表示引用前面的“love”
13)<或\b:锚定词首(支持vi和grep),其后面的任意字符必须作为单词首部出现,如 <love或\blove
14)>或\b:锚定词尾(支持vi和grep),其前面的任意字符必须作为单词尾部出现,如 love>或love\b
<, \b
>, \b
match the empty string at the beginning and end of a word. ; 匹配单词开始和结束的空字符串
\b匹配:匹配单词边缘的空字符串
\b, <, >:都不做真正的匹配,只是用来判断单词是不是独立存在
\b
[root@whl ~]# echo 'good job' | grep '\bgood\b'
good job
[root@whl ~]# echo 'goodjob' | grep '\bgood\b'
\<
[root@whl ~]# echo 'goodjob' | grep 'job\>'
goodjob
\>
[root@whl ~]# echo 'goodjob' | grep 'job\>'
goodjob
\< \>
[root@whl ~]# echo 'goodjob' | grep '\<good\>'
[root@whl ~]# echo 'good job' | grep '\<good\>'
good job
特殊符号不作为单词的一部分
[root@whl ~]# echo 'good.job' | grep '\<good\>'
good.job
正则表达式字符集
[[:alnum:]] 匹配任意一个字母或者数字,等价于[A-Za-z0-9]
[root@whl ~]# echo '123aB?' | grep '[[:alnum:]]'
123aB?
[[:alpha:]] 匹配任意一个字母,等价于[A-Za-z]
[root@whl ~]# echo 'aB131' | grep '[[:alpha:]]'
aB131
[[:digit:]] 匹配任意一个数字,等价于0-9
[root@whl ~]# echo 'aB1234567890' | grep '[[:digit:]]'
aB1234567890
[[:lower:]] 匹配任意一个小写字母,等价于a-z
[root@whl ~]# echo 'aB1234567890' | grep '[[:lower:]]'
aB1234567890
[[:upper:]] 匹配任意一个大写字母,等价于A-Z
[root@whl ~]# echo 'aB1234567890' | grep '[[:upper:]]'
aB1234567890
[[:space:]] 匹配任意一个空白符,包括空格、制表符、换行符以及分页符
[root@whl ~]# echo -e 'aB \t \n 1234567890' | grep -Pz 'aB[[:space:]]*1234567890'
aB
1234567890
[[:blank:]] 匹配空格和制表符
[root@whl ~]# echo -e ‘aB \t 1234567890’ | grep -Pz ‘aB[[:blank:]]*1234567890’
aB 1234567890
[[:graph:]] 匹配任意一个看得见的可打印字符,不包括空白字符
[[:print:]]
匹配任何一个可以打印的字符,包括空白字符,但是不包括控制字符、字符串
结束符‘\0’、EOF文件结束符(-1)
[[:cntrl:]] 匹配任何一个控制字符,即ASCII字符集中的前32个字符。例如换行符、制表符等
[root@whl ~]# echo -e '\t' | grep '[[:cntrl:]]'
[root@whl ~]#
[[:punct:]] 匹配任何一个标点符号,例如“[]”、“{}”或者“,”等
[root@whl ~]# echo '[],{}' | grep '[[:punct:]]'
[],{}
[[:xdigit:]] 匹配十六进制数字,即0-9、a-f以及A-F
[root@whl ~]# echo '1234567890abcdefghhABCDEFGHKS' | grep '[[:xdigit:]]'
1234567890abcdefghhABCDEFGHKS
?:代表的是?之前的正则表达式重复0次到1次:最少没有,最多一次
[root@whl ~]# echo "123123123" | grep -Po '123?'
123
123
123
[root@whl ~]# echo "123123123" | grep -Po '3?'
3
3
3
(s|t)-> 匹配的时候的或
s|t: s|t
只能匹配0401-0419
[root@whl ~]# echo 0411 | grep -P '^040[0-9]|^041[0-9]$'
0411
[root@whl ~]# echo 0401 | grep -P '^040[0-9]|^041[0-9]$'
0401
[root@whl ~]# echo 00410 | grep -P '^040[0-9]|^041[0-9]$'
[root@whl ~]# echo 004100 | grep -P '^040[0-9]|^041[0-9]$'