一、简介
正则表达式分为 基本正则表达式 和 扩展正则表达式 ,两者其实基本用法都一样,但是在某些符号的写法上有差异,接下来,我将一步一步带领大家学习正则表达式
演示文本:
# vim test1.txt
root ROOT Rootabroot
tom jerrytom Tom
123 56789
SElinux=disabled
#selinux firewalld
abc ABC .rootROOT
abcrootabcc
abcabc
babcabcabcbaaa abcbbb
aaaaa bbbbbb
tm ttm ttttttm
# head -10 /etc/passwd > passwd
二、基本正则表达式:入门
^:表示锚定行首,此字符后面的任意内容必须出现在行首,才能匹配。
匹配以root开头的行
# grep "^root" test1.txt
$:表示锚定行尾,此字符前面的任意内容必须出现在行尾,才能匹配。
匹配以root结尾的行
# grep "root$" test1.txt
^$:表示匹配空行,这里所描述的空行表示”回车”,而”空格”或”tab”等都不能算作此处所描述的空行。
每一行的结尾默认都会有$结尾符,在vim中可以使用set list显示$
匹配以$开头的行,也就是空行
# grep "^$" test1.txt
grep -n -v -e "^$" -e "^#" test1.txt
^abc$:表示abc独占一行时,会被匹配到。
# grep -n "^abc$" test1.txt
\<或者\b :匹配单词边界,表示锚定词首,其后面的字符必须作为单词首部出现。
# grep "\<root" test1.txt
# grep "\broot" test1.txt
\>或者\b :匹配单词边界,表示锚定词尾,其前面的字符必须作为单词尾部出现。
# grep "root\>" test1.txt
# grep "root\b" test1.txt
\B:匹配非单词边界,与\b正好相反。
# grep "\Broot" test1.txt
# grep "root\B" test1.txt
# grep "\Broot\B" test1.txt
总结(用自己的话阐述这些符号的作用)
^
$
^$
^abc$
\<或者\b
\>或者\b
\B
三、基本正则表达式:连续匹配次数
* 表示前面的字符连续出现任意次,包括0次。
# grep "t*m" test1.txt
# grep "b*" test1.txt
# grep "\(abc\)*" test1.txt
. 表示任意单个字符。
# grep "a....b" test1.txt
.* 表示任意长度的任意字符,与通配符中的*的意思相同。
# grep "a.*b" test1.txt
# grep "r.*t" test1.txt
\? 表示匹配其前面的字符0或1次
# grep "abc\?" test1.txt
\+ 表示匹配其前面的字符至少1次,或者连续多次,连续次数上不封顶。
# grep "abc\+" test1.txt
\{n\} 表示前面的字符连续出现n次,将会被匹配到。
# grep "a\{3\}" test1.txt
# grep "\(abc\)\{2\}" test1.txt
# grep "\<\(abc\)\{2\}\>" test1.txt
\{x,y\} 表示之前的字符至少连续出现x次,最多连续出现y次,都能被匹配到,换句话说,只要之前的字符连续出现的次数在x与y之间,即可被匹配到。
# grep "a\{2,4\}" test1.txt
# grep "\(abc\)\{1,3\}" test1.txt
# grep "\<\(abc\)\{1,3\}\>" test1.txt
\{,n\} 表示之前的字符连续出现至多n次,最少0次,都会被匹配到。
# grep "a\{,4\}" test1.txt
\{n,\} 表示之前的字符连续出现至少n次,才会被匹配到。
# grep "a\{3,\}" test1.txt
注意:
如果匹配的是一个单词整体,需要小括号括起来,例如: \(abc\)
总结(用自己的话阐述这些符号的作用)
*
.
.*
\?
\+
\{n\}
\{n,\}
\{,m\}
\{n,m\}
四、基本正则表达式:常用匹配
字符
. 表示匹配任意单个字符
* 表示匹配前面的字符任意次,包括0次
[ ] 表示匹配指定范围内的任意单个字符
[^ ] 表示匹配指定范围外的任意单个字符
[0-9] 匹配0-9的数字
[a-z] 匹配a-z的小写字母
[A-Z] 匹配A-Z的大写字母
[a-zA-Z] 匹配所有的大小写字母
[a-zA-Z0-9] 匹配所有的大小写字母和数字
分组
\( \) 表示分组,我们可以将其中的内容当做一个整体,分组可以嵌套。
\(abc\) 表示将abc当做一个整体去处理。
转义符\
例如.是匹配任意单个字符,那么\.表示的就是.原本的意思
要注意,如果转移\\,那么需要用单引号,不能用双引号
举例:匹配ip地址
# ifconfig | grep "\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}"
# grep "\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}$" /etc/sysconfig/network-scripts/ifcfg-ens33
总结(用自己的话阐述这些符号的作用)
[ ]
[^ ]
[0-9]
[a-z]
[A-Z]
[a-zA-Z]
[a-zA-Z0-9]
\( \)
\(abc\)
基本正则大总结:
^
$
^$
^abc$
\<或者\b
\>或者\b
\B
*
.
.*
\?
\+
\{n\}
\{n,\}
\{,m\}
\{n,m\}
[ ]
[^ ]
[0-9]
[a-z]
[A-Z]
[a-zA-Z]
[a-zA-Z0-9]
\( \)
\(abc\)
五、扩展正则表达式
扩展正则与基本正则的区别
扩展正则
( ) 表示分组
(ab) 表示将ab当做一个整体去处理。
? 表示匹配其前面的字符0或1次
+ 表示匹配其前面的字符至少1次,或者连续多次,连续次数上不封顶。
{n} 表示前面的字符连续出现n次,将会被匹配到。
{x,y} 表示之前的字符至少连续出现x次,最多连续出现y次,都能被匹配到,换句话说,只要之前的字符连续出现的次数在x与y之间,即可被匹配到。
{,n} 表示之前的字符连续出现至多n次,最少0次,都会陪匹配到。
{n,}表示之前的字符连续出现至少n次,才会被匹配到。
"|"在扩展正则表达式中,表示”或”
基本正则
\( \)
\(abc\)
\?
\+
\{n\}
\{n,\}
\{,m\}
\{n,m\}
\|
扩展正则与基本正则表达式的用法基本相同,但是扩展正则的写法更加简练,例如
扩展正则写法
# egrep "(abc){1,3}" test1.txt
# egrep "^(root|bin)" passwd
基本正则写法
# grep "\(abc\)\{1,3\}" test1.txt
# grep "^\(root\|bin\)" passwd
将括号里面看作是一个整体,表示为root或bin,所以"^(root|bin)"表示以root开头的行或者以bin开头的行
扩展正则总结
常用符号
. 表示任意单个字符。
* 表示前面的字符连续出现任意次,包括0次。
.* 表示任意长度的任意字符,与通配符中的*的意思相同。
\ 表示转义符,当与正则表达式中的符号结合时表示符号本身。
| 表示"或者"之意
[ ]表示匹配指定范围内的任意单个字符。
[^ ]表示匹配指定范围外的任意单个字符。
次数匹配相关
? 表示匹配其前面的字符0或1次
+ 表示匹配其前面的字符至少1次,或者连续多次,连续次数上不封顶。
{n} 表示前面的字符连续出现n次,将会被匹配到。
{x,y} 表示之前的字符至少连续出现x次,最多连续出现y次,都能被匹配到,换句话说,只要之前的字符连续出现的次数在x与y之间,即可被匹配到。
{,n} 表示之前的字符连续出现至多n次,最少0次,都会陪匹配到。
{n,}表示之前的字符连续出现至少n次,才会被匹配到。
位置边界匹配相关
^:表示锚定行首,此字符后面的任意内容必须出现在行首,才能匹配。
$:表示锚定行尾,此字符前面的任意内容必须出现在行尾,才能匹配。
^$:表示匹配空行,这里所描述的空行表示"回车",而"空格"或"tab"等都不能算作此处所描述的空行。
^abc$:表示abc独占一行时,会被匹配到。
\<或者\b :匹配单词边界,表示锚定词首,其后面的字符必须作为单词首部出现。
\>或者\b :匹配单词边界,表示锚定词尾,其前面的字符必须作为单词尾部出现。
\B:匹配非单词边界,与\b正好相反。
分组与后向引用
( ) 表示分组,我们可以将其中的内容当做一个整体,分组可以嵌套。
(ab) 表示将ab当做一个整体去处理。
"|"在扩展正则表达式中,表示"或",多数在分组里面使用
六、实战演练
举例1:按照规定找出合法邮箱,满足如下条件
1、邮箱字符串中必须包含"@"符
2、"@"符前面的字符只能是小写字母或数字,不能包含特殊符号。
3、"@"符前面的字符数量至少需要4个,至多为16个
4、邮箱必须以"com"、"net"、"org"、"edu"等顶级域名结尾(此处为了方便演示,不判断更多的域名)
5、顶级域名之前必须包含一个”点”,换句话说就是,邮箱必须以"com"、"net"、"org"、"edu"结尾
6、"@"与"."之间的字符数量不能超过12个,不能低于2个
7、"@"与"."之间的字符只能是小写字母或数字,不能包含特殊符号
基本正则
# grep "[a-z0-9]\{4,16\}@[a-z0-9]\{2,12\}\.\<\(com\|net\|org\|edu\)$" qq.txt
扩展正则
# egrep "[a-z0-9]{4,16}@[a-z0-9]{2,12}\.\<(com|net|org|edu)$" qq.txt
思考:
# 为什么要添加\<词首符号?
为了确保必须以.com结尾,不会出现.aaacom的情况
举例二:匹配IP地址
# cat ip.txt
192.168.58.100
256.256.55.55
255.255.0.256
59.59.58.58
0.5.5.5
198.198.198.300
8.8.114.114
没有经过校验
基本正则
grep "\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}" ip.txt
扩展正则
egrep "([0-9]{1,3}\.){3}[0-9]{1,3}" ip.txt
经过校验
第一个
1-9 [1-9]
10-99 [1-9][0-9]
100-199 1[0-9]{2}
200-249 2[0-4][0-9]
250-255 25[0-5]
第二、三、四
0-9 [0-9]
10-99 [1-9][0-9]
100-199 1[0-9]{2}
200-249 2[0-4][0-9]
250-255 25[0-5]
注意:
1、此处校验IP[0-9]不能使用\d表示
2、使用|表示或,使用()表示一个整体
基本正则
grep "\([1-9]\|[1-9][0-9]\|1[0-9]\{2\}\|2[0-4][0-9]\|25[0-5]\)\.\([0-9]\|[1-9][0-9]\|1[0-9]\{2\}\|2[0-4][0-9]\|25[0-5]\)\.\([1-9]\|[1-9][0-9]\|1[0-9]\{2\}\|2[0-4][0-9]\|25[0-5]\)\.\([1-9]\|[1-9][0-9]\|1[0-9]\{2\}\|2[0-4][0-9]\|25[0-5]\)$" ip.txt
扩展正则
egrep "([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$" ip.txt
七、正则表达式的其他字符、
[[:alpha:]] 表示任意大小写字母
[[:lower:]] 表示任意小写字母
[[:upper:]] 表示任意大写字母
[[:digit:]] 表示0到9之间的任意单个数字(包括0和9)
[[:alnum:]] 表示任意数字或字母
[[:space:]] 表示任意空白字符,包括"空格"、"tab键"等。
[[:punct:]] 表示任意标点符号
[0-9]与[[:digit:]]等效
[a-z]与[[:lower:]]等效
[A-Z]与[[:upper:]]等效
[a-zA-Z]与[[:alpha:]]等效
[a-zA-Z0-9]与[[:alnum:]]等效
[^0-9]与[^[:digit:]]等效
[^a-z]与[^[:lower:]]等效
[^A-Z]与[^[:upper:]]等效
[^a-zA-Z]与[^[:alpha:]]等效
[^a-zA-Z0-9]与[^[:alnum:]]等效
#简短格式并非所有正则表达式解析器都可以识别
\d 表示任意单个0到9的数字
\D 表示任意单个非数字字符
\t 表示匹配单个横向制表符(相当于一个tab键)
\s表示匹配单个空白字符,包括"空格","tab制表符"等
\S表示匹配单个非空白字符
\1 表示引用整个表达式中第1个分组中的正则匹配到的结果。
\2 表示引用整个表达式中第2个分组中的正则匹配到的结果。