正则表达式

本文详细介绍了正则表达式的基本概念、元字符、基本正则表达式(BRE)和扩展正则表达式(ERE)的用法,通过实例展示了如何在Unix/Linux环境中使用grep、sed等工具进行文本过滤和编辑。正则表达式是文本处理的强大工具,通过掌握元字符和语法,可以更高效地处理字符串和文本文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、 什么是正则表达式

1.1 正则表达式简介

​ 所谓正则表达式,实际上就是用来描述某些字符串匹配规则的工具,简单地说,正则表达式是对文本进行过滤的工具。而正则表达式之所以拥有过滤文本的功能,是因为它定义了一系列的元字符,通过元字符配合其他普通字符来表达出一种规则(匹配规则),只有符合该规则的文本才能保留下来。由于正则表达式语法简练、功能强大,得到了许多变成语言的支持,包括Java、C++、Perl以及Shell。

​ 比如ls .txt。通常情况下,我们称“*”为通配符。当shell遇到该符号时,会将其解释为“任意的字符串”。与通配符类似,正则表达式也是用来匹配文本的,与之相比,正则表达式能够更加准确的描述用户的需求。

​ 正则表达式在Unix和Linux中得到广泛的应用,常见支持正则表达式的Unix工具如下:

​ grep命令族:用于匹配文本行

​ sed流编辑器:用于编辑文本

​ awk:用于处理字符串的语言

​ 掌握正则表达式,可以更好地利用这些工具。

解释:

​ 字符 字母和数字

​ 字符串 word 词

​ 文本行 文件中的行

1.2 如何学习正则表达式

​ 1)重点在于理解元字符

​ 元字符在正则表达式中占核心地位,正则表达式最终是由元字符表达出来。理解和掌握元字符的涵义,才能达到灵活运用的地步。

​ 2)掌握好正则表达式的语法

​ 正则表达式之所以简练,是因为它有严格的语法。例如“*”它匹配该符号前面那一个普通字符出现0次或多次,也就是说,它的作用范围仅限于紧挨着该字符前面的一个字符。

二、基本正则表达式(Basic Regular Expression,BRE)

​ 又称标准的正则表达式,是最早指定的正则表达式规范,其所定义的元字符主要有以下几种:

1、 行首定位符 “^”

2、 行尾定位符 “$”

3、 单个字符匹配 “.”

​ 匹配任意单个字符,包括空格,但不包括换行符“\n”

4、 限定符 “*”

​ 匹配其前导字符可以出现任意次数(0次或多次)

5、 字符集合匹配 “[]”

​ 匹配方括号中任意一个字符 //例如:[abc]、[0-9]、[A-Z]

6、 字符集合不匹配 “[^]”

​ 不匹配其中列出的任意字符

在示例之前,先来用sed删除空行:

​ [root@mha_master opt]# sed -i “/^$/d” regexp.txt

示例1:过滤出以字母“a”开头的行

​ [root@mha_master opt]# grep “^a” regexp.txt

示例2:过滤出以“C”结尾的行

​ [root@mha_master opt]# grep “C$” regexp.txt

示例3:过滤出总共有3个字符,该字符串以’a’开头,紧跟着第二个字符是“b”,第三个字符也是最后一个字符为“c”的行

​ [root@mha_master opt]# grep ‘^abc$’ regexp.txt

示例4:匹配以a开头,c结尾,中间为除了换行符之外的任意一个字符的行

​ [root@mha_master opt]# grep ‘^a.c$’ regexp.txt

示例5:匹配以d开头,d结尾,中间为除了换行符之外的任意两个字符的行

​ [root@mha_master opt]# grep ‘^d…d$’ regexp.txt //可以使用多个“.”匹配多个字符

示例6:匹配a和b之间没有s或者有多个s的行

​ [root@mha_master opt]# grep ‘^as*b$’ regexp.txt

示例7:匹配出字符串,该字符串只有三个字符且以字母开头、第二个字符是数字,第三个字符为字母。

​ [root@mha_master opt]# grep ‘1[0-9][a-z]$’ regexp.txt

示例8:只匹配出来“a8c”

​ [root@localhost 桌面]# grep ‘a[a-z]c$’ regexp.txt

​ a c

​ a.c //前两行结果明显不符合期望

​ a8c

​ [root@mha_master opt]# grep ‘a[a-z|.|\ ][a-z]$’ regexp.txt

其他标准正则表达式支持的元字符

7.次数匹配—数量词

x{m,n}

​ 区间表达式(次数匹配),匹配字符x重复的次数区间。该表达式表示x最少重复m次,最多重复n次

x{m,}

​ 表示x至少重复出现m次

x{,m}

​ 表示x至多重复出现m次

x{m}

​ 表示x重复m次

{}示例:

[root@localhost 桌面]# grep ‘^as{2,3}b$’ regexp.txt

assb

asssb

[root@localhost 桌面]# grep ‘^as{2,}b$’ regexp.txt

assb

asssb

[root@localhost 桌面]# grep ‘^as{2}b$’ regexp.txt

assb

匹配出abbbbbc

[root@localhost 桌面]# grep ‘^a.{5}c$’ regexp.txt

abbbbbc

匹配出电话号码(11位)

[复制代码](javascript:void(0)😉

[root@A tmp]# cat 1.txt 
ab
asb
assb
asssb
13912345678
18198765432
39718973748719749]
313141
[root@A tmp]# grep '^[0-9]\{11\}$' 1.txt 
13912345678
18198765432

[复制代码](javascript:void(0)😉

8.词首词尾匹配

<

​ 词首定位符,\取其转义之意,< 前,首,词首

>

​ 词尾定位符,\取其转义之意,> 后,尾,词尾

词首字、词尾子匹配符示例:

[root@mha_master opt]# grep “<welcome” regexp.txt

welcome to vfast!

[root@mha_master opt]# grep “done>” regexp.txt

well done!

9.向前引用 ()

​ 定义字表达式的开始和结束位置,在后续正则表达式中可以通过转义字符来引用正则表达式。最多可以定义9个字表达式,通过\1~\9来引用。

​ 如:

​ [root@localhost 桌面]# grep ‘(love).*\1’ regexp.txt

​ love me tender,love me sweet!

​ 字表达式(love).*\1,表示匹配两个love中间包含任意个字符的文本行,其中\1表示引用前面定义的第一个字表达(love)

三、 扩展的正则表达式(Extended Regular Expression,ERE)

​ 扩展的正则表达式支持比标准的正则表达式更多的元字符,扩展的正则表达式对有些标准正则表达式所支持的元字符并不支持(区间表达式次数匹配),但上面介绍的6种元字符是支持的,并且意义完全相同。下面重点来看下扩展的正则表达式中新增的元字符。

Unix命令:

​ egrep或者grep -E 、 sed -r

1) 限定符 “+”

​ 限定前面的字符至少出现一次

限定符 “*****” 限定前面的字符出现0****次或多次

2) 限定符 “?”

​ 限定前面的字符出现0次或1次

3) 竖线“|”和小括号“()”

​ 竖线“|”表示多个表达式之间**“或”**的关系,语法为:

​ expression1|expression2|expression3…

​ 小括号(分组)表示一组可选值的集合。竖线和小括号经常放在一起用,表示一组可选值。

4) 扩展正则表达式取消了次数匹配{m,n}语法中的转义符,在使用这种语法时,不需要再添加转义符也不能添加,添加会匹配失败。

总结:标准正则表达式元字符:^ $ . * [] [^] {}

​ 扩展正则表达式元字符:+ ? “|”和“()” {}

示例1:匹配出a和c之间字符“c”至少出现1次的字符串

​ [root@localhost 桌面]# grep ‘^ac+c$’ regexp.txt //基本正则写(不支持+符号),不行

​ [root@localhost 桌面]# grep -E ‘^ac+c$’ regexp.txt //还得扩展的正则

​ acc

​ accc

示例2:匹配a打头,b结尾,中间有0个或一个s的字符串

​ [root@mha_master opt]# grep -E ‘^as?b$’ regexp.txt

示例3:匹配字符串,该字符串共有三个字符,a打头,c结尾,中间是数字或者是字符

​ [root@mha_master opt]# grep -E ‘^a([a-z]|[0-9])c$’ regexp.txt

标准正则中[]表示匹配其中的任意一个字符,也可用竖线加小括号来表达:

​ [abc] 等价于 (a|b|c)

下面三组也是等价的:

​ (Jeffrey|Jeffery)

​ Jeff(rey|ery)

​ Jeff(re|er)y

示例4:字符串a开头,b结尾,中间s至少出现一次,最多出现2次

[root@mha_master opt]# grep -E ‘^as{1,2}b$’ regexp.txt

四、 正则表达式中的普通字符

​ 正则表达式是由一系列字符组成,其中包括元字符和普通字符。前面看过了很多元字符,现在来了解普通字符该如何匹配。

​ 通常情况下,普通字符通常结合方括号表达式表示:

​ [cC]hina

​ [^hello]

​ [a-zA-Z]

​ [0123456789]

​ [0-9]

​ 除了这些之外,还可以使用posix字符集,POSIX字符集是为了在不同国家的字符编码中保持一致,而定义的一些特殊字符类(扩展的正则):

字符类说明
[:alnum:]匹配任意一个字母或数字,等价于[a-zA-Z0-9]
[:alpha:]匹配任意一个字母,等价于a-zA-Z
[:digit:]匹配任意一个数字,等价于0-9
[:lower:]匹配任意一个小写字母,等价于a-z
[:upper:]匹配任意一个大写字母,等价于A-Z
[:space:]匹配任意一个空白字符,包括空格、制表符、换行符
[:blank:]匹配空格和制表符
[:graph:]匹配任意一个看得见的可打印字符,不包括空白字符
[:print:]匹配任意一个可以打印的字符,包括空白字符,但是不包括控制字符、EOF文件结束符
[:cntrl:]匹配任意一个控制字符(百度百科:控制字符),即ACSII字符集中的前32个字符,如:换行符、制表符等
[:punct:]匹配任意一个标点符号,如”[]”、”{}”、 ,“”
[:xdigit:]匹配16进制数,即0-9、a-f以及A-F

单词:

​ alphabet 字母表

​ digit 数字

​ blank 空白的

​ punctuation 标点符号

示例:过滤出符合指定格式的电话号码

​ [root@mha_master opt]# grep -E ‘400-[[:digit:]]{3}-[[:digit:]]{4}$’ regexp.txt

​ 400-123-5678

运算符的优先级:

运算符说明
\转义字符
[]方括号表达式
()分组
*、+、?、{m}、{m,}、{m,n}限定符
普通字符按照从做到右的顺序
^、$定位符
|或运算

演示分组“()”:匹配IP地址

[root@mha_master opt]# grep -E ‘^([[:digit:]]{1,3}.){3}[[:digit:]]{1,3}$’ regexp.txt

202.106.0.20

10.0.0.1

256.45.32.1 //这是一个不正确的IP

精确匹配:

grep -E “^([0-9]{1,2}|1[0-9]{2}|2[0-4][0-9]|25[0-5]).([0-9]{1,2}|1[0-9]{2}|2[0-4][0-9]|25[0-5]).([0-9]{1,2}|1[0-9]{2}|2[0-4][0-9]|25[0-5]).([0-9]{1,2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])$” regexp.txt

练习:

1、从regexp.txt中匹配出书写正确的邮箱地址:

​ 这里认为邮箱用户名至少是6~18位的字母和数字组成,邮箱账号均为163.com的邮箱。

​ [root@mha_master opt]# grep -E ‘2{6,18}@163.com$’ regexp.txt

2、源文件url.txt的内容如下:

www.baidu.com
http://www.baidu.com
https://www.baidu.com
http://wwwbaiducom
baidu.com
baidu

匹配出以http或https开头,其后为“:”,并且含有“.”的串

[root@localhost 桌面]# grep -E ‘https?.*.’ url.txt

http://www.baidu.com

https://www.baidu.com

3、Email匹配

示例文件内容为:

hfutwyy@qq.com
aaaa@
aaa@.com
_aaa@gmail.com

@@baidu.com

匹配以字母数字或者下划线开头的多个字符,其后有一个@之后有多个字母数字或者下划线,其中有一个.号

[root@localhost 桌面]# grep -E ‘3@[[:alnum:]|_].’ email

hfutwyy@qq.com

_aaa@gmail.com

4、匹配身份证号:18位

前17位必须为数字,最后一位是数字或字母

grep -E ‘4{17}[0-9A-Z]$’ danny.txt

idu

匹配出以http或https开头,其后为“:”,并且含有“.”的串

[root@localhost 桌面]# grep -E ‘https?.*.’ url.txt

http://www.baidu.com

https://www.baidu.com

3、Email匹配

示例文件内容为:

hfutwyy@qq.com
aaaa@
aaa@.com
_aaa@gmail.com

@@baidu.com

匹配以字母数字或者下划线开头的多个字符,其后有一个@之后有多个字母数字或者下划线,其中有一个.号

[root@localhost 桌面]# grep -E ‘5@[[:alnum:]|_].’ email

hfutwyy@qq.com

_aaa@gmail.com

4、匹配身份证号:18位

前17位必须为数字,最后一位是数字或字母

grep -E ‘6{17}[0-9A-Z]$’ danny.txt


  1. a-z ↩︎

  2. [:alnum:] ↩︎

  3. [:alnum:]|_ ↩︎

  4. 0-9 ↩︎

  5. [:alnum:]|_ ↩︎

  6. 0-9 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值