- A+
在本博客中,"正则表达式"为一系列文章,如果你想要从头学习怎样在Linux中使用正则,可以参考此系列文章,直达链接如下:
"正则"系列的每篇文章都建立在前文的基础之上,所以,请按照顺序阅读这些文章,否则有可能在阅读中遇到障碍。
前文中一直在说,在Linux中,正则表达式可以分为"基本正则表达式"和"扩展正则表达式"。
我们已经认识了"基本正则表达式",现在,我们来认识一下"扩展正则表达式"。
有了之前的基础,学习"扩展正则表达式"简直不要太轻松。
之前说过,有些符号是通用的,不管是在"基本正则表达式"中,还是在"扩展正则表达式"中,这些通用的符号所表达的意思都是相同的。
那么,我们先来看看哪些符号是通用的,看完之后你会信心大增,如下字符都是通用的:
上述符号,在基本正则表达式中与扩展正则表达式中的用法完全相同。
有没有感觉,70%都是通用的,那么我们来动手试试。
在总结grep命令时,我们提到过,grep命令默认只支持基本正则表达式,如果想要让grep命令能够支持扩展的正则表达式,则需要使用"-E"选项,示例如下
上图中,grep命令使用了"-E"选项,表示grep命令会把"正则表达式"中的符号当成"扩展正则表达式"去理解,而不再使用默认的"基本正则表达式"。
但是由于"[A-Z]"是通用的,所以,不管是否使用扩展正则表达式,"[A-Z]"都表示单个大写字母。
刚才说过,70%的符号都是通用的,那么剩下的30%呢?
其实,剩下的30%也都差不多,与基本正则表达式相比,反而更加简单了,不信?我们就来看看。
在基本正则表达式中,\{n\} 表示前面的字符连续出现n次,将会被匹配到。
在扩展正则表达式中,{n} 表示前面的字符连续出现n次,将会被匹配到。
在基本正则表达式中,\( \) 表示分组,\(ab\) 表示将ab当做一个整体去处理。
在扩展正则表达式中,( ) 表示分组,(ab) 表示将ab当做一个整体去处理。
在写法上,"扩展正则表达式"的写法是不是更加简练呢?示例如下
如上图所示,当使用"扩展正则表达式"时,在"书写"方面,反而省力不少,最终匹配到的文本却是相同的,是不是很方便?
看完了上述示例,我想你对扩展正则表达式应该已经有了一个初步的印象了。
那么,我们就来介绍一下,有哪些符号在"扩展正则表达式"中变得更加简练了。
在扩展正则表达式中:
( ) 表示分组
(ab) 表示将ab当做一个整体去处理。
\1 表示引用整个表达式中第1个分组中的正则匹配到的结果。
\2 表示引用整个表达式中第2个分组中的正则匹配到的结果。
? 表示匹配其前面的字符0或1次
+ 表示匹配其前面的字符至少1次,或者连续多次,连续次数上不封顶。
{n} 表示前面的字符连续出现n次,将会被匹配到。
{x,y} 表示之前的字符至少连续出现x次,最多连续出现y次,都能被匹配到,换句话说,只要之前的字符连续出现的次数在x与y之间,即可被匹配到。
{,n} 表示之前的字符连续出现至多n次,最少0次,都会陪匹配到。
{n,}表示之前的字符连续出现至少n次,才会被匹配到。
看了上述总结以后,是不是已经想要放弃使用"基本正则表达式"了呢?因为与之相比,扩展正则表达式才更符合我们这些懒人的习惯,而且,扩展正则表达式的可读性也更高,毕竟很多符号少了前面的"\",可读性就变强了。
扩展正则表达式中,还有一个常用的符号,是基本正则表达式中所没有的,它就是"|"
注:按住键盘的 "shift键" 和 "\"键 ,就可以打出"|"
"|"在扩展正则表达式中,表示"或",这样说不容易理解,我们来看个小例子,就能明白,示例文件内容如下。
如果,我们想要从上例文本中找到以"com"结尾的行,我们该怎么办呢?我们可以使用如下命令。
同理,如果我们想要从示例文本中找出以"net"结尾的行,可以使用如下命令。
那么,如果我们想要从示例文本找出,以"com"结尾,或者以"net"结尾的行,我们该怎么办呢?
这时候,我们就需要用到"|"
"|"在扩展正则表达式中表示"或者",所以,我们可以使用如下表达式
上图中的扩展正则使用了分组符号"( )","(com|net)"表示将括号内的内容看做一个整体,而括号内的内容为"com|net",它表示"com或者net",所以,"(com|net)$"就表示以com或者net结尾的行。是不是很简单?
那么,我们就趁热打铁,通过实际练习,来熟悉一下"扩展正则表达式"吧。
仍然以刚才的示例文件作为测试文件,假设,我们想要查找出测试文本中的"合法邮箱",我们应该怎么做呢?
既然是要找出"合法邮箱",那么,我们则必须事先定义,满足哪些条件的邮箱才属于合法邮箱。
所以,我们规定,如果一个邮箱属于合法邮箱,那么必须满足如下条件。
1、邮箱字符串中必须包含"@"符。
2、"@"符前面的字符只能是小写字母或数字,不能包含特殊符号。
3、"@"符前面的字符数量至少需要4个,至多为16个。
4、邮箱必须以"com"、"net"、"org"、"edu"等顶级域名结尾(此处为了方便演示,不判断更多的域名)。
5、顶级域名之前必须包含一个"点",换句话说就是,邮箱必须以".com"、".net"、".org"、".edu"结尾。
6、"@"与"."之间的字符数量不能超过12个,不能低于2个。
7、"@"与"."之间的字符只能是小写字母或数字,不能包含特殊符号。
好了,了解了合法邮箱的规则以后,我们就可以开始编写正则表达式了,我们可以使用如下正则,查找文本中的合法邮箱。
如果你觉得上述正则稍微有些复杂,不容易理解,那么可以将其拆分成几个部分去理解,拆分后的每一部分,可以与之前的"合法邮箱条件"一一对应,如下图所示。
这样看,是不是容易理解多了,好了,赶快自己动手实验一下吧。
小结
我认为,有了之前基础的你,搞定"扩展正则表达式",肯定是分分钟的事情,所以,我们就对"扩展正则表达式"进行一下总结吧。
关于"扩展正则表达式",就总结到这里,希望能够帮助到你~~

2020年7月21日 下午2:43 沙发
grep -E “[a-z0-9]{4,16}@[a-z0-9]{2,12}\.com$” mail.txt
请问一下,我这个为什么匹配不到cccom结尾的呢?
2020年4月20日 下午3:45 板凳
不太明白\. 与. 又有什么区别,()$ 与(())$有什么区别
[monitor@linux quota]$ grep -E “[a-z0-9]{4,16}@[a-z0-9]{2,12}.(com|net|edu)$” REG -n
1:zhang@163.com
4:213213@net.com
[monitor@linux quota]$ grep -E “[a-z0-9]{4,16}@[a-z0-9]{2,12}\.(com|net|edu)$” REG -n
1:zhang@163.com
4:213213@net.com
[monitor@linux quota]$
2020年7月21日 下午2:52 1层
@小白 .代表的是任意一个字符,而 \. 使用了转义处理,代表的是字符.
如果内容既有.com 还有#com的话,不加\既会匹配到.com,又可以匹配到#com
[root@agent ~]# grep -E “[a-z0-9]{4,16}@[a-z0-9]{2,12}\.com$” mail.txt
testregex@163.com
[root@agent ~]#
[root@agent ~]# grep -E “[a-z0-9]{4,16}@[a-z0-9]{2,12}.com$” mail.txt
testregex@163.com
testregex@163#com
2020年4月20日 下午12:01 地板
打卡,博主帅
2019年11月24日 下午10:58 4楼
请问下楼主,如果要去匹配中文字符,应该怎么操作呢?好像没有讲到中文字符的提取呢
2019年9月23日 下午8:59 5楼
本来想提问邮箱为什么加上\<,发现下面评论已经有了。
多谢老师,写得很好
2019年9月24日 上午9:13 1层
@陈飞 能帮到你就好,加油~
2019年7月12日 下午3:54 6楼
有幸拜读,写的很好,加深了我对正则的认识,其实扩展正则跟一般程序语言中的正则很类似
2019年7月5日 上午11:26 7楼
感谢🙏!这几天连续读了两遍,正则表达式没有比你介绍得更清楚了!希望能继续讲解其它常用命令,比如sed, xargs。
2019年7月6日 下午8:41 1层
@skywind 嗯嗯,抽出空闲会在复习一下别的,重新总结一遍,加油~
2019年6月28日 下午12:27 8楼
条件4写成(com|net|org|edu)$和锚定词首的结果一样,老师这里加上\<是有什么考虑吗?
2019年6月28日 下午4:05 1层
@rubuzhao 如果一样的话就是当时没有进行任何测试,为了保险,那样写的,当时应该是和评论中的”福长”同学的想法一样,如果测试了一样,就没有什么必要了,加油~~
2019年3月22日 上午11:52 9楼
我试了,可以不用词首瞄定符,求楼主解答。
cat testd
zhenguo@139.com
zhenguo@163.net
zhenguo@139.com.cn zhenguo@ss.net
zhen@eeeeee.sssscom.org.net
[root@localhost software]# grep -E “[0-9a-z]{4,16}@[a-z0-9]{2,12}\.(\<(com|net|edu|org))$" testd
zhenguo@163.net
zhenguo@139.com.cn zhenguo@ss.net
[root@localhost software]# grep -E "[0-9a-z]{4,16}@[a-z0-9]{2,12}\.((com|net|edu|org))$" testd
zhenguo@163.net
2019年1月9日 下午2:00 10楼
正则表达式的修饰符,大神能介绍一下不
2018年9月22日 下午5:40 11楼
学海无涯啊
2017年11月28日 下午7:29 12楼
条件4中一定要用/<锚定吗
2018年8月6日 下午10:33 1层
@re 同样的疑问
2018年12月30日 下午2:18 2层
@wesharp “必须”二字看到了吗?如果不加\<的话,可能会以匹配到csadcom结尾
2019年1月31日 下午4:26 3层
@福长 感觉可以不需要
2017年6月16日 下午5:40 13楼
[root@localhost regex]# ifconfig |grep -E ‘([0-9]{1,3}\.)\1([0-9]{1,3})’
楼主你好,我输入如上命令,按道理应该是grep出IP地址前面192.168.122之类的,为什么结果不对呢?
2017年6月16日 下午6:06 1层
@yanan001 正则写错了,没有必要用\1进行后向引用,用类似这样的表达式应该可以
([0-9]{1,3}\.){3}([0-9]{1,3})
2017年6月12日 下午9:47 14楼
以前是基本/扩展混淆用
现在终于分开了
2017年6月12日 下午9:50 1层
@echo 慢慢的就都清楚了,加油,兄弟