目录
前言
什么是正则表达式?
REGEXP: Regular Expressions,由一类特殊字符及文本字符所编写的模式,
其中有些字符(元字符)不表示字符字面意义,而表示控制或通配的功能,
类似于增强版的通配符功能,但与通配符不同,通配符功能是用来处理文件名,而正则表达式是处理文本内容中字符。
正则表达式被很多程序和开发语言所广泛支持:vim, less,grep,sed,awk, nginx,mysql等
主要用来匹配字符串(命令结果,文本内容)
通配符
通配符只用于匹配文件名、目录名等,不能用于匹配文件内容。(而且是已存在的文件或者目录)
通配符主要是为了方便用户对文件或者目录的描述,
例如用户仅仅需要以".sh"结尾的文件时,使用通配符就能很方便地实现。
各个版本的shell都有通配符,这些通配符是一些特殊的字符,
用户可以在命令行的参数中使用这些字符,进行文件名或者路径名的匹配。
shell将把与命令行中指定的匹配规则符合的所有文件名或者路径名作为命令的参数,
然后执行这个命令。
常用通配符
符号 | 说明 | 举例 |
* | 匹配任意一个或多个字符 | ls *.txt |
? | 匹配一个任意字符 | ls ?.txt |
[] | 匹配l[]中任意单个字符 | ls [a-z].tx |
正则表达式
-基本正则表达式 -----所有特殊符号都要加 转义符
-扩展正则表达式
元字符
字符 | 说明 |
. | 匹配任意单个字符,可以是一个汉字 |
() | 使用转义符,只表示\(\) |
[] | 匹配指定范围内的任意单个字符,示例:[dn] [0-9] [] [a-zA-Z] [:alpha:] |
[^] | 匹配指定范围外的任意单个字符,示例:[^dn] [^a.z] |
[:alnum:] | 字母和数字 [0-9] [a-z] [0-9] [a-z] |
[:alpha:] | 代表任何英文大小写字符,亦即 [A-Z], [a-z] |
[:lower:] | 小写字母,示例:[[:lower:]],相当于[a-z] |
[:upper:] | 大写字母 [A-Z] |
[[:blank:]] | 空白字符(空格和制表符) |
[:space:] | 包括空格、制表符(水平和垂直)、换行符、回车符等各种类型的空白,比[:blank:]包含的范围广 |
[:cntrl:] | 不可打印的控制字符(退格、删除、警铃...) |
[:digit:] | 十进制数字 |
[:xdigit:] | 十六进制数字 |
[:graph:] | 可打印的非空白字符 |
[:print:] | 可打印字符 |
[:punct:] | 标点符号 |
\w | 匹配单词构成部分,等价于[_[:alnum:]] |
\W | 匹配非单词构成部分,等价于[^_[:alnum:]] |
\S | 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。 |
示列
- .
[root@localhost ~]# ls /etc/ | grep 'rc\.' #只匹配已rc.开头的文件
#点值表示点需要转义
rc.d
rc.local
[root@localhost ~]# ls /opt | grep "t." #过滤出仅包含字母"t"后跟任何其他字符的行。
[root@localhost ~]# grep 'r..t' /etc/passwd
#r..t ..代表任意两个字符
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
[root@localhost ~]# echo abc |grep a.c
#表示原来的点需要加\转义
abc
[root@localhost ~]# echo abc |grep a\.c
#不加引号有时匹配会有出入
abc
[root@localhost ~]# echo abc |grep 'a\.c'
#标准格式需要加'' 或者""
- []
[root@localhost ~]# ls |grep '[fhtx].txt'
#匹配[]中任意一个字符
f.txt
h.txt
t.txt
x.txt
[root@localhost ~]# ls [a-d].txt
#通配符
a.txt A.txt b.txt B.txt c.txt C.txt d.txt
[root@localhost ~]# ls | grep '[a-d].txt'
#真正的小写在正则表达式中
a.txt
b.txt
c.txt
d.txt
- [^]
[root@localhost ~]# ls |grep '[^a-z].txt'
#显示非小写字母
A.txt
B.txt
[root@localhost ~]# ls |grep '[^a.z].txt'
#“[^a.z]”表示不匹配字母“a”或“z”的任何字符
- space空格
[root@localhost ky15]# grep [[:space:]] 123.txt
hhh
jj
kkk
[a-zA-Z] #同时匹配大小写
表示次数特殊字符
符号 | 说明 |
* | 匹配前面的字符任意次,包括0次,贪婪模式:尽可能长的匹配 |
.* | 任意长度的任意字符,包括0次,也就是匹配所有 |
\? | 匹配其前面的字符出现0次或1次,即:可有可无 |
\+ | 匹配其前面的字符出现最少1次,即:肯定有且 >=1 次 |
\{n\} | 匹配前面的字符=n次 |
\{m,n\} | 匹配前面的字符至少m次,至多n次 |
\{,n\} | 匹配前面的字符至多n次,<=n |
\{n,\} | 匹配前面的字符至少n次 |
示列
[root@localhost ~]# echo google | grep 'go\{2\}gle'
#代表前面的o出现2次
google
[root@localhost ~]# echo gooooogle |grep 'go\{2,\}gle'
#代表前面的o出现2次以上
gooooogle
[root@localhost ~]# echo gooooogle |grep 'go\{2,5\}gle'
#代表前面的o出现2次以上5次以下
gooooogle
[root@localhost ~]# echo goooooogle |grep 'go\{2,5\}gle'
#表示前面的o最少出现2次,最多出现5次,匹配不到
[root@localhost opt]# echo goooooogle |grep 'go\{,5\}gle'
#匹配前面的字符至多n次
[root@localhost ~]# echo goooooogle |grep 'go*gle'
#表示0次到任意次
goooooogle
[root@localhost ~]# echo ggle |grep "go*gle"
ggle
[root@localhost ~]# echo gggle |grep "go*gle"
#grep 包含最前面的g不匹配
gggle
[root@localhost ~]# echo gdadadadgle |grep "g.*gle"
#.*代表任意匹配所有
gdadadadgle
[root@localhost ~]# echo ggle |grep "go\?gle"
# \?一次或者0次
ggle
[root@localhost ~]# echo gogle |grep "go\?gle"
gogle
[root@[root@localhost ~]# echo google |grep "go\+gle"
#一个以上
google
[root@localhost ~]# echo gogle |grep "go\+gle"
gogle
[root@localhost ~]# echo ggle |grep "go\+gle"
[root@localhost ~]# echo google |grep "go\?gle"
ifconfig ens33|grep netmask|grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+'|head -n1
ifconfig ens33|grep netmask|grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'
位置锚定
符号 | 说明 |
^ | 行首锚定, 用于模式的最左侧 |
$ | 行尾锚定,用于模式的最右侧 |
^root$ | 用于模式匹配整行 (单独一行 只有root) |
^$ | 空行 |
^[[:space:]]*$ | 空白行 |
\< 或 \b | 词首锚定,用于单词模式的左侧(连续的数字,字母,下划线都算单词内部) |
\> 或 \b | 词尾锚定,用于单词模式的右侧 |
\<root\> | 匹配整个单词 |
示例
思考过滤出不是已#号开头的非空行
[root@localhost ~]#grep "^[^#]" /etc/fstab
[root@localhost data]#grep "^google$" test.txt
#只匹配google 这个字符
[root@localhost ~]#grep "^[[:space:]]*$" /etc/fstab
[root@localhost ~]#echo hello-123 |grep "\b123"
#除了 字母 数字 下划线其他都算 单词的分隔符
hello-123
[root@localhost ~]#echo hello-123 |grep "\bhello"
hello 123
[root@localhost opt]# echo hello-123 |grep "\bo-123" #已o为开头就匹配不到了,只能定义开头和结尾
分组或其他
符号 | 说明 |
() | 分组 |
\| | 或者 |
示例
[root@localhost ~]#echo abccc |grep "abc\{3\}"
abccc
[root@localhost ~]#echo abcabcabc |grep "\(abc\)\{3\}"
#分组 匹配abc
abcabcabc
[root@localhost ~]#echo abcabcabc |grep "\(ab\)\{3\}" 思考能不能匹配,为什么不能匹配?要连续的出现才能匹配
[root@localhost opt]# echo golgogle | grep '\(go\)\{1\}'
golgogle
[root@localhost opt]# echo golgogle | grep '\(go\)\{1\}gle' #只能匹配后面的
golgogle
[root@localhost ~]#echo 1abc |grep "1\|2abc"
#只匹配了1
1abc
[root@localhost ~]#echo 1abc2abc |grep "\(1\|2\)abc"
#1abc或者2abc
1abc2abc
扩展正则表达式(表示字符相差不大)
grep -E 必须用 sed -r
或者
egrep
表示次数
字符 | 说明 |
* | 匹配前面字符任意次 |
? | 0或1次 |
+ | 1次或多次 |
{n} | 匹配n次 |
{m,n} | 至少m,至多n次 |
{,n} | 匹配前面的字符至多n次,<=n,n可以为0 |
{n,} | 匹配前面的字符至少n次,<=n,n可以为0 |
表示分组
符号 | 说明 | 示列 |
() | 将多个字符捆绑在一起,当作一个整体处理 | (root) |
| | 或者 | a|b #a或b C|cat #C或cat (C|c)at #Cat或cat |
试题练习
- 表示邮箱
echo "544564317@qq.com" | grep -E "[0-9]+@[a-z]+\.[a-z]+"
[root@localhost opt]# echo "cicifireway@163.com" | grep -E "[a-z]+@[0-9]+\.[a-z]+"
cicifireway@163.com
[root@localhost opt]# echo "CICIfireway@163.com" | grep -E "[a-zA-Z]+@[0-9]+\.[a-z]+"
CICIfireway@163.com
- 表示手机号
echo "13770725194"|grep -E "\b1[3456789][0-9]{9}\b"
[root@localhost opt]# echo "13770725194" | grep -E "1[3456789][0-9]{9}"
13770725194