前言
在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。
一、正则表达式
1.正则表达式概述
正则表达式通常用于判断语句中,用来检查某一字符串是否满足某一格式。
正则表达式是由普通字符与元字符组成。普通字符包括小写字母、数字、标点符号及一些其他符号。元字符是指在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符)在目标对象中的出现模式。
2.正则表达式的分类
正则表达式根据从POSIX BRE或者POSIX ERE标准可以分为基本正则表达式和扩展正则表达式。
基本正则表达式
支持的工具:grep、egrep、sed、 awk,注意grep要配合-E或者-P使用。
| 元字符 | 含义及用法 |
| \ | 转义字符,用于取消特殊符号的含义,例: \! 、 \n 、 \$等 |
| ^ | 匹配字符串开始的位置,例:^a、^the、^#、^[a-z] |
| $ | 匹配字符串结束的位置,例: word$、^$匹配空行 |
| . | 匹配除`\n`之外的任意的一个字符,例: go.d、g..d。如果想要匹配包含\\n字符可以使用 [.\n] |
| * | 匹配前面子表达式0次或者多次,例: `goo*d`、 `go.*d` |
| [list] | 匹配list列表中的一个字符,例: `go[ola]d`,`[abc]`、`[a-z]`、`[a-z0-9]`、`[0-9]`匹配任意一位数字 |
| [^list] | 匹配任意非list列表中的一个字符,例:`[^0-9]`、`[^A-Z0-9]`、`[^a-z]`匹配任意一位非小写字母 |
| \{n\} | 匹配前面的子表达式n次,例: `go\{2\}d`、 `[0-9]\{2\}`匹配两位数字 |
| \{n,\} | 匹配前面的子表达式不少于n次,例: `gol{2,l}d`、`[0-9]\{2,\}`匹配两位及两位以上数字 |
| \{n,m\} | 匹配前面的子表达式n到m次,例 : `go\{2,3\}d`、`[0-9]\{2,3\}`匹配两位到三位数字。 |
| \w | 匹配包括下划线的任何单词字符。 |
| \W | 匹配任何非单词字符。等价于`[^A-Za-z0-9_]`。 |
| \d | 匹配一个数字字符。 |
| \D | 匹配一个非数字字符。等价于`[^0-9]`。 |
| \s | 空白符。 |
| \S | 非空白符。 |
扩展正则表达式
支持的工具:`egrep`、`awk`,注意:使用`grep`要配合`-E`或者`-P`使用,`sed`要配合`-r`使用。
| 元字符 | 含义及用法 |
| + | 匹配前面子表达式1次以上,例: go+d,将匹配至少一个o,如god、good、goood等 |
| ? | 匹配前面子表达式0次或者1次,例: `go?d`,将匹配`gd`或`god` |
| () | 将括号中的字符串作为一个整体,例1: `g(oo)+d`,将匹配`oo`整体1次以上,如`good`、`gooood`等 |
| | | 以或的方式匹配字符串,例:`g(oo|la)d`,将匹配`good`或者 `glad` |
3.正则表达式的使用
* ^ $的用法
[root@localhost ~]# cat testfile6
gd
god
good
goood
goooadcd
gooooooodddd
abccba
abccba
abccba123
oooogooood
ooooogd
gold
goad
[root@localhost ~]# grep goo*d testfile6
#查询一串字符中有goo*d字样,且o有0个或多个,此字符串可以不在开头或结尾
good
goood
gooooooodddd
oooogooood
[root@localhost ~]# grep "^goo*d$" testfile6
#查询以g开头d结尾,中间的o有0个或多个
god
good
goood
[] \[^\]的用法
[root@localhost ~]# grep "go[ola]d" testfile6
#查询一个字符,其中有一段以go开头d结尾,中间的o、l、a这几种字符中的一种
good
gold
goad
[root@localhost ~]# grep "go[ola]*d" testfile6
#查询一个字符,其中有一段以go开头d结尾,中间的o、l、a这几种字符中的一个或多个
god
good
goood
goooadcd
gooooooodddd
oooogooood
gold
goad
[root@localhost ~]# grep "^[^a-g]" testfile6
#匹配除了a-g开头的字符
oooogooood
ooooogd
\\{n\\} \\{n,\\} 的用法
[root@localhost ~]# grep "go\{2\}d" testfile6
#匹配good字符,其中\{2\}只会匹配前面的o两次
good
[root@localhost ~]#
[root@localhost ~]# grep "go\{2,\}d" testfile6
#匹配go..d,其中o至少2次及以上
good
goood
gooooooodddd
oooogooood
4.常见例题
电话例题
找出区号025开头的号码,且号码与区号间可以是空格、-、没有,号码必须是5或者8开头的八位数。
[root@localhost ~]# cat iphone.sh
02588888888
025-55555555555
025 112345678
025 54321678ada
025-abc88888
025-58432109
028-85461913
0251-52765421
解题思路
先将电话拆分为3段,第一段找出区号,第二段筛选出号码与区号之间的分隔符,第三段号码后几位。区号025开头。^是以什么为开头,用()将025作为一个整体
^(025)
号码与区号间可以是空格、-、没有。将题目要求的空格和-写入\[\],由于?是前面的子表达式0次或1次,0次就符合题目要求的没有
[ -]?
号码必须是5或者8开头的八位数。用\[\]确认是5或8数字开头的号码,然后再匹配0-9的7位数结尾的数
[58][0-9]{7}$
总体输出如下:
[root@localhost ~]# egrep "^(025)[ -]?[58][0-9]{7}$" iphone.sh
egrep: warning: egrep is obsolescent; using grep -E
02588888888
025-58432109
电子邮箱例题
根据 `用户名@子域名.[二级域名].顶级域` 格式找出符合要求的电子邮箱
[root@localhost ~]# cat mail.sh
zhangsan123@qq.com
li si@163.com
wang@wu@sina.com
zhao liu@126.com
qianqi@sina.com.cn
解题思路
将邮箱拆分为三段,第一段用户名,第二段子域名二级域,第三段顶级域
用户名@:长度要求在6-18位,任意大小写英文,任意数字,除了@符号和空格以外的其它任意符号字符,开头只能是 \_ 或者字母
^([a-zA-Z_][^@ ]{5,17})@
子域名.\[二级域名\]:长度任意,符号只能包含 - \_ .
[a-zA-Z0-9\_\-\.]+(\.[a-zA-Z0-9\_\-\.]+)?
.顶级域名: 长度在2-5,任意大小写英文
\.([a-zA-Z]{2,5})$
总体输出如下:
[root@localhost ~]# grep -E "^([a-zA-Z_][^@ ]{5,17})@[a-zA-Z0-9\_\-\.]+(\.[a-zA-Z0-9\_\.]+)?\.([a-zA-Z]{2,5})$" mail.sh
zhangsan123@qq.com
qianqi@sina.com.cn
7422

被折叠的 条评论
为什么被折叠?



