Shell脚本之正则表达式

277 阅读2分钟

通配符

通配符:linux命令中可使用通配符替代或者识别某一些文件名。

  • *:代表的是0个或者多个任意字符。
  • ?:代表的是有且只有1个任意字符。
  • [xxxxxx]:代表的是任意一个中括号内的列表中的字符。

通配符通常会用在模糊查询的场景中,正则表达式匹配的精确度比通配符更高。

  • 通配符是用来处理文件名。
  • 正则表达式是处理文本内容中字符。必须加双引号。

正则表达式

REGEXP: Regular Expressions,由一类特殊字符及文本字符所编写的模式,其中有些字符(元字符)不表示字符字面意义,而表示控制或通配的功能,类似于增强版的通配符功能。

正则表达式被很多程序和开发语言所广泛支持:vim、less、grep、sed、awk、nginx、mysql 等,主要用来匹配字符串(命令结果,文本内容)。

正则表达式—通常用于判断语句中,用来检查某一字符串是否满足某一格式。

正则表达式是由普通字符与元字符组成:

  • 普通字符 包括大小写字母、数字、标点符号及一些其他符号。
  • 元字符 是指在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符或表达式)在目标对象中的出现模式。

基础正则表达式

元字符:

元字符含义
\*转义字符,用于取消特殊符号的含义
$匹配字符串结束的位置
.匹配除\n之外的任意的一个字符,有且仅有一个
*匹配前面子表达式0次或者多次
[list]匹配list列表中的一个字符,例:go[ola]d,[abc]、[a-z]、[a-z0-9]
[^list]匹配任意非list列表中的一个字符,例:[ ^A-Z0-9],[ ^a-z]匹配任意一位非小写字母
[[:alpha:]]代表任意一个大小写英文字母,相当于[A-Za-z]
[:[:digit:]]代表任意一个十进制数字,相当于[0-9]
[[:alnum:]]代表任意一个大小写英文字母及数字,相当于[A-Za-z0-9]
\ {n\ }匹配前面的子表达式n次,例:go{2}d、 '[0-9]{2}'匹配两位数字
\ {n,\ }匹配前面的子表达式不少于n次,例:go{2,}d'[0-9]{2,}'匹配两位及两位以上数字
\ {n,m\ }匹配前面的子表达式n到m次,例:go{2,3}d'[0-9]{2,3}'匹配两位到三位数字

转义字符\

\ 可以把一些特殊的符号转换成普通的符号字符,还可以把一些普通字符转换成特殊功能。

转义字符将特殊的符号转换成普通字符
\ &单个&代表后台运行
\ l单个 l 代表“或”
\ !单个 ! 代表取反
\ =单个=代表复制或者字符判断
\ $单个$代表引用变量
转义字符将普通字符转换成特殊功能
\n转换后是换行符
\t转换后是制表符
\r转换后是回车符
\w匹配包括下划线的任何单词字符
\W匹配任何非单词字符。等价于"[^A-Za-z0-9_]"
\d匹配一个数字字符
\D匹配一个非数字字符。等价于[^0-9]
\s空白符
\S非空白符

^匹配开头,$匹配结尾

[root@localhost ~]# cat 1.txt
aaaa
bbbb
cccc
aabbcc
aaabbbccc
aaaccc
bbbccc
[root@localhost ~]# grep "^a" 1.txt
aaaa
aabbcc
aaabbbccc
aaaccc
[root@localhost ~]# grep "^b" 1.txt
bbbb
bbbccc
[root@localhost ~]# grep "b$" 1.txt
bbbb

image.png

.和*

点:匹配除\n之外的任意的一个字符,有且仅有一个。

星:匹配前面子表达式0次或者多次。

[root@localhost ~]# cat 2.txt
good
gooood
god
goood
goooooooood
[root@localhost ~]# grep "go.d" 2.txt
good
[root@localhost ~]# grep "go.*d" 2.txt
good
gooood
god
goood
goooooooood
[root@localhost ~]# grep "go*d" 2.txt
good
gooood
god
goood
goooooooood
[root@localhost ~]# grep "goo*d" 2.txt
good
gooood
god
goood
goooooooood

image.png

[list]

[list] 匹配括号内的任意一个字符,只能匹配单个字符。

[ ^list] ,^在括号内表示取反。即匹配括号内字符以外的任意一个字符,只能匹配单个字符。

[root@localhost ~]# cat 3.txt 
gd
god
good
goood
golbd
goolbd
goalad
[root@localhost ~]# grep "go[olb]d" 3.txt
good
[root@localhost ~]# grep "go[^lb]d" 3.txt
good

image.png

复合使用

1、^与$复合使用

[root@localhost ~]# grep "^goo*d$" 3.txt
god
good
goood

2、^与 [^list] 复合使用

image.png

\{n\}

\{n\}匹配前面的子表达式n次。

[root@localhost ~]# grep "go\{2,\}d" 3.txt
good
goood
[root@localhost ~]# grep "go\{3,\}d" 3.txt
goood

image.png

\{n,m\}

\{n,m\} 匹配前面的子表达式n到m次。

[root@localhost ~]# grep "go\{2,3\}d" 3.txt
good
goood
[root@localhost ~]# grep "go\{1,2\}d" 3.txt
god
good

image.png

扩展正则表达式

元字符含义
+匹配前面的表达式1次及以上
匹配前面的表达式0次或者1次
()将括号中的字符串作为一个整体
l以"或"的方式匹配字符串

1. +

+:匹配前面的子表达式1次及以上(至少1次)。

[root@localhost ~]# egrep "go+d" 3.txt
god
good
goood
[root@localhost ~]# egrep "go*d" 3.txt
gd
god
good
goood

image.png

2. ?

?:匹配前面的表达式0次或者1次

[root@localhost ~]# egrep "go?d" 3.txt
gd
god

3. ()

( ):将括号中的字符串作为一个整体

[root@localhost ~]# egrep "g(oo)d" 3.txt
good
[root@localhost ~]# egrep "g(oo)*d" 3.txt
gd
good

image.png

4. |

| :以"或"的方式匹配字符串。

[root@localhost ~]# egrep "g(oo|lb)d" 3.txt
good
[root@localhost ~]# egrep "g(o|b)d" 3.txt
god

案例

匹配电话号码

  1. 匹配 025 开头的区号。

  2. 电话号码要5 或者 8开头的八位数。

  3. 格式如下:

 区号 号码
 区号-号码
 区号号码
 123
  1. 要求全号码格式匹配。
 [root@yuji sh]# cat hh.txt
 02588888888          //符合
 025-5555555555      
 025 12345678
 025 54321678         //符合
 025ABC88888
 025-85432109         //符合
 0251-85432109
 0025-85432109
 [root@yuji sh]# egrep "^(025)[- ]?[58][0-9]{7}$" hh.txt
 02588888888
 025 54321678
 025-85432109

匹配电子邮箱

  1. 用户名:长度要求在6-18位,任意大小写英文,任意数字,除了@符号和空格以外的其它任意符号字符,开头只能是 _ 或者字母。
  2. 子域名.[二级域名]:长度任意,符号只能包含 - _ .
  3. .顶级域名:长度在2-5,任意大小写英文。
  4. 完整匹配。
 [root@localhost ~]# cat mail.txt
 zhangsan123@qq.com
 li_si@163.com
 wang@wu@sina.com
 zhao liu@126.com
 qianqi@sina.com.cn
 [root@localhost ~]# egrep "(^[a-zA-Z_][^@ ]{5,17})@([a-zA-Z0-9-_.]+).[a-zA-Z]{2,5}$" mail.txt
 zhangsan123@qq.com
 qianqi@sina.com.cn