揭开正则表达式的神秘面纱
引言
正则表达式(regular expression)就是用一个“字符串”来描述一个特征,然后去验证另一个“字符串”是否符合这个特征。比如 表达式“ab+” 描述的特征是“一个 'a' 和 任意个 'b' ”,那么 'ab', 'abb', 'abbbbbbbbbb' 都符合这个特征。
正则表达式可以用来:(1)验证字符串是否符合指定特征,比如验证是否是合法的邮件地址。(2)用来查找字符串,从一个长的文本中查找符合指定特征的字符串,比查找固定字符串更加灵活方便。(3)用来替换,比普通的替换更强大。
正则表达式学习起来其实是很简单的,不多的几个较为抽象的概念也很容易理解。之所以很多人感觉正则表达式比较复杂,一方面是因为大多数的文档没有做到由浅入深地讲解,概念上没有注意先后顺序,给读者的理解带来困难;另一方面,各种引擎自带的文档一般都要介绍它特有的功能,然而这部分特有的功能并不是我们首先要理解的。
文章中的每一个举例,都可以点击进入到测试页面进行测试。闲话少说,开始。
1. 正则表达式规则
1.1 普通字符
字母、数字、汉字、下划线、以及后边章节中没有特殊定义的标点符号,都是"普通字符"。表达式中的普通字符,在匹配一个字符串的时候,匹配与之相同的一个字符。
举例1:表达式 "c",在匹配字符串 "abcde" 时,匹配结果是:成功;匹配到的内容是:"c";匹配到的位置是:开始于2,结束于3。(注:下标从0开始还是从1开始,因当前编程语言的不同而可能不同)
举例2:表达式 "bcd",在匹配字符串 "abcde" 时,匹配结果是:成功;匹配到的内容是:"bcd";匹配到的位置是:开始于1,结束于4。
1.2 简单的转义字符
一些不便书写的字符,采用在前面加 "/" 的方法。这些字符其实我们都已经熟知了。
表达式 |
可匹配 |
/r, /n |
代表回车和换行符 |
/t |
制表符 |
// |
代表 "/" 本身 |
表达式 |
可匹配 |
/^ |
匹配 ^ 符号本身 |
/$ |
匹配 $ 符号本身 |
/. |
匹配小数点(.)本身 |
这些转义字符的匹配方法与 "普通字符" 是类似的。也是匹配与之相同的一个字符。
举例1:表达式 "/$d",在匹配字符串 "abc$de" 时,匹配结果是:成功;匹配到的内容是:"$d";匹配到的位置是:开始于3,结束于5。
1.3 能够与 '多种字符' 匹配的表达式
表达式 |
可匹配 |
/d |
任意一个数字,0~9 中的任意一个 |
/w |
任意一个字母或数字或下划线,也就是 A~Z,a~z,0~9,_ 中任意一个 |
/s |
包括空格、制表符、换页符等空白字符的其中任意一个 |
. |
小数点可以匹配除了换行符(/n)以外的任意一个字符 |
举例1:表达式 "/d/d",在匹配 "abc123" 时,匹配的结果是:成功;匹配到的内容是:"12";匹配到的位置是:开始于3,结束于5。
举例2:表达式 "a./d",在匹配 "aaa100" 时,匹配的结果是:成功;匹配到的内容是:"aa1";匹配到的位置是:开始于1,结束于4。
1.4 自定义能够匹配 '多种字符' 的表达式
使用方括号 [ ] 包含一系列字符,能够匹配其中任意一个字符。用 [^ ] 包含一系列字符,则能够匹配其中字符之外的任意一个字符。同样的道理,虽然可以匹配其中任意一个,但是只能是一个,不是多个。
表达式 |
可匹配 |
[ab5@] |
匹配 "a" 或 "b" 或 "5" 或 "@" |
[^abc] |
匹配 "a","b","c" 之外的任意一个字符 |
[f-k] |
匹配 "f"~"k" 之间的任意一个字母 |
[^A-F0-3] |
匹配 "A"~"F","0"~"3" 之外的任意一个字符 |
举例1:表达式 "[bcd][bcd]" 匹配 "abc123" 时,匹配的结果是:成功;匹配到的内容是:"bc";匹配到的位置是:开始于1,结束于3。
举例2:表达式 "[^abc]" 匹配 "abc123" 时,匹配的结果是:成功;匹配到的内容是:"1";匹配到的位置是:开始于3,结束于4。
1.5 修饰匹配次数的特殊符号
前面章节中讲到的表达式,无论是只能匹配一种字符的表达式,还是可以匹配多种字符其中任意一个的表达式,都只能匹配一次。如果使用表达式再加上修饰匹配次数的特殊符号,那么不用重复书写表达式就可以重复匹配。
使用方法是:"次数修饰"放在"被修饰的表达式"后边。比如:"[bcd][bcd]" 可以写成 "[bcd]{2}"。
表达式 |
作用 |
{n} |
表达式重复n次,比如:"/w{2}" 相当于 "/w/w";"a{5}" 相当于 "aaaaa" |
{m,n} |
表达式至少重复m次,最多重复n次,比如:"ba{1,3}"可以匹配 "ba"或"baa"或"baaa" |
{m,} |
表达式至少重复m次,比如:"/w/d{2,}"可以匹配 "a12","_456","M12344"... |
? |
匹配表达式0次或者1次,相当于 {0,1},比如:"a[cd]?"可以匹配 "a","ac","ad" |
+ |
表达式至少出现1次,相当于 {1,},比如:"a+b"可以匹配 "ab","aab","aaab"... |
* |
表达式不出现或出现任意次,相当于 {0,},比如:"/^*b"可以匹配 "b","^^^b"... |
举例1:表达式 "/d+/.?/d*" 在匹配 "It costs $12.5" 时,匹配的结果是:成功;匹配到的内容是:"12.5";匹配到的位置是:开始于10,结束于14。
举例2:表达式 "go{2,8}gle" 在匹配 "Ads by goooooogle" 时,匹配的结果是:成功;匹配到的内容是:"goooooogle";匹配到的位置是:开始于7,结束于17。
1.6 其他一些代表抽象意义的特殊符号
表达式 |
作用 |
^ |
与字符串开始的地方匹配,不匹配任何字符 |
$ |
与字符串结束的地方匹配,不匹配任何字符 |
/b |
匹配一个单词边界,也就是单词和空格之间的位置,不匹配任何字符 |
举例4:表达式 "/bend/b" 在匹配 "weekend,endfor,end" 时,匹配结果是:成功;匹配到的内容是:"end";匹配到的位置是:开始于15,结束于18。
表达式 |
作用 |
| |
左右两边表达式之间 "或" 关系,匹配左边或者右边 |
( ) |
(1). 在被修饰匹配次数的时候,括号中的表达式可以作为整体被修饰 |
举例6:表达式 "(go/s*)+" 在匹配 "Let's go go go!" 时,匹配结果是:成功;匹配到内容是:"go go go";匹配到的位置是:开始于6,结束于14。
2. 正则表达式中的一些高级规则
2.1 匹配次数中的贪婪与非贪婪
表达式 |
匹配结果 |
(d)(/w+) |
"/w+" 将匹配第一个 "d" 之后的所有字符 "xxxdxxxd" |
(d)(/w+)(d) |
"/w+" 将匹配第一个 "d" 和最后一个 "d" 之间的所有字符 "xxxdxxx"。虽然 "/w+" 也能够匹配上最后一个 "d",但是为了使整个表达式匹配成功,"/w+" 可以 "让出" 它本来能够匹配的最后一个 "d" |
表达式 |
匹配结果 |
(d)(/w+?) |
"/w+?" 将尽可能少的匹配第一个 "d" 之后的字符,结果是:"/w+?" 只匹配了一个 "x" |
(d)(/w+?)(d) |
为了让整个表达式匹配成功,"/w+?" 不得不匹配 "xxx" 才可以让后边的 "d" 匹配,从而使整个表达式匹配成功。因此,结果是:"/w+?" 匹配 "xxx" |
2.2 反向引用 /1, /2...
2.3 预搜索,不匹配;反向预搜索,不匹配
格式:"(?!xxxxx)",所在缝隙的右侧,必须不能匹配 xxxxx 这部分表达式。
举例4:表达式 "do(?!/w)" 在匹配字符串 "done, do, dog" 时,只能匹配 "do"。在本条举例中,"do" 后边使用 "(?!/w)" 和使用 "/b" 效果是一样的。
反向预搜索:"(?<=xxxxx)","(?<!xxxxx)"
3. 其他通用规则
还有一些在各个正则表达式引擎之间比较通用的规则,在前面的讲解过程中没有提到。
3.1 表达式中,可以使用 "/xXX" 和 "/uXXXX" 表示一个字符("X" 表示一个十六进制数)
形式 |
字符范围 |
/xXX |
编号在 0 ~ 255 范围的字符,比如:空格可以使用 "/x20" 表示 |
/uXXXX |
任何字符可以使用 "/u" 再加上其编号的4位十六进制数表示,比如:"/u4E2D" |
3.2 在表达式 "/s","/d","/w","/b" 表示特殊意义的同时,对应的大写字母表示相反的意义
表达式 |
可匹配 |
/S |
匹配所有非空白字符("/s" 可匹配各个空白字符) |
/D |
匹配所有的非数字字符 |
/W |
匹配所有的字母、数字、下划线以外的字符 |
/B |
匹配非单词边界,即左右两边都是 "/w" 范围或者左右两边都不是 "/w" 范围时的字符缝隙 |
3.3 在表达式中有特殊意义,需要添加 "/" 才能匹配该字符本身的字符汇总
字符 |
说明 |
^ |
匹配输入字符串的开始位置。要匹配 "^" 字符本身,请使用 "/^" |
$ |
匹配输入字符串的结尾位置。要匹配 "$" 字符本身,请使用 "/$" |
( ) |
标记一个子表达式的开始和结束位置。要匹配小括号,请使用 "/(" 和 "/)" |
[ ] |
用来自定义能够匹配 '多种字符' 的表达式。要匹配中括号,请使用 "/[" 和 "/]" |
{ } |
修饰匹配次数的符号。要匹配大括号,请使用 "/{" 和 "/}" |
. |
匹配除了换行符(/n)以外的任意一个字符。要匹配小数点本身,请使用 "/." |
? |
修饰匹配次数为 0 次或 1 次。要匹配 "?" 字符本身,请使用 "/?" |
+ |
修饰匹配次数为至少 1 次。要匹配 "+" 字符本身,请使用 "/+" |
* |
修饰匹配次数为 0 次或任意次。要匹配 "*" 字符本身,请使用 "/*" |
| |
左右两边表达式之间 "或" 关系。匹配 "|" 本身,请使用 "/|" |
3.4 括号 "( )" 内的子表达式,如果希望匹配结果不进行记录供以后使用,可以使用 "(?:xxxxx)" 格式
举例1:表达式 "(?:(/w)/1)+" 匹配 "a bbccdd efg" 时,结果是 "bbccdd"。括号 "(?:)" 范围的匹配结果不进行记录,因此 "(/w)" 使用 "/1" 来引用。
3.5 常用的表达式属性设置简介:Ignorecase,Singleline,Multiline,Global
表达式属性 |
说明 |
Ignorecase |
默认情况下,表达式中的字母是要区分大小写的。配置为 Ignorecase 可使匹配时不区分大小写。有的表达式引擎,把 "大小写" 概念延伸至 UNICODE 范围的大小写。 |
Singleline |
默认情况下,小数点 "." 匹配除了换行符(/n)以外的字符。配置为 Singleline 可使小数点可匹配包括换行符在内的所有字符。 |
Multiline |
默认情况下,表达式 "^" 和 "$" 只匹配字符串的开始 ① 和结尾 ④ 位置。如: ①xxxxxxxxx②/n 配置为 Multiline 可以使 "^" 匹配 ① 外,还可以匹配换行符之后,下一行开始前 ③ 的位置,使 "$" 匹配 ④ 外,还可以匹配换行符之前,一行结束 ② 的位置。 |
Global |
主要在将表达式用来替换时起作用,配置为 Global 表示替换所有的匹配。 |
4. 其他提示
4.1 如果想要了解高级的正则引擎还支持那些复杂的正则语法,可参见本站 DEELX 正则引擎的说明文档。
4.2 如果要要求表达式所匹配的内容是整个字符串,而不是从字符串中找一部分,那么可以在表达式的首尾使用 "^" 和 "$",比如:"^/d+$" 要求整个字符串只有数字。
4.3 如果要求匹配的内容是一个完整的单词,而不会是单词的一部分,那么在表达式首尾使用 "/b",比如:使用 "/b(if|while|else|void|int……)/b" 来匹配程序中的关键字。
4.7 或 "|" 的左右两边,对某个字符最好只有一边可以匹配,这样,不会因为 "|" 两边的表达式因为交换位置而有所不同。
揭开正则表达式的神秘面纱相关推荐
- [转]揭开正则表达式的神秘面纱
揭开正则表达式的神秘面纱 关闭高亮 [原创文章,转载请保留或注明出处:http://www.regexlab.com/zh/regref.htm] 引言 正则表达式(regular expressio ...
- 【转】揭开正则表达式的神秘面纱
原文地址 http://www.regexlab.com/zh/regref.htm 引言 正则表达式(regular expression)就是用一个"字符串"来描述一个特征,然 ...
- [装载]揭开正则表达式的神秘面纱
正则表达式(regular expression)就是用一个"字符串"来描述一个特征,然后去验证另一个"字符串"是否符合这个特征.比如 表达式"ab+ ...
- 了解黑客的关键工具---揭开Shellcode的神秘面纱
2019独角兽企业重金招聘Python工程师标准>>> ref: http://zhaisj.blog.51cto.com/219066/61428/ 了解黑客的关键工具---揭开 ...
- 揭开PC-Lint9的神秘面纱
前言 今天,又定位了一个令人懊恼的C++内存使用异常问题,最终结果,竟然是减少接口类的方法后,为了避免编译错误,顺手添加的强制类型转换导致的. 对于这样的问题,我们碰到很多很多次了.没有这样的问题,我 ...
- 未来已来?揭开量子计算机的神秘面纱
从第一台现代计算机ENIAC的诞生到个人PC时代的降临,从互联网概念的提出到移动互联的疾跑,在这个信息年代里,变革正以前所未有的速度改变着我们熟悉的世界.熟悉的生活. 作为个人,我们早已习惯于智能计算 ...
- ASP.NET 运行时详解 揭开请求过程神秘面纱
对于ASP.NET开发,排在前五的话题离不开请求生命周期.像什么Cache.身份认证.Role管理.Routing映射,微软到底在请求过程中干了哪些隐秘的事,现在是时候揭晓了.抛开乌云见晴天,接下来就 ...
- linux操作系统说课稿,信息技术《揭开LINUX的神秘面纱》教案范文
信息技术<揭开LINUX的神秘面纱>教案范文 教学目标: 1.会启动LINUX系统: 2.会关闭LINUX系统: 3.LINUX基本界面的认识. 教学重点: 1.会启动LINUX系统: 2 ...
- 冰河浅析 - 揭开木马的神秘面纱(下)
冰河浅析 - 揭开木马的神秘面纱(下) 作者:· shotgun·yesky 四.破解篇(魔高一尺.道高一丈) 本文主要是探讨木马的基本原理, 木马的破解并非是 ...
最新文章
- TensorFlow(7)卷积神经网络实战(1)(可视化)
- thinkphp的匹配php后缀,ThinkPHP的后缀操作方法配置 罢工了
- Java的数据类型的挑选
- Webwork 学习之路【02】前端OGNL试练
- jMeter 里如何使用 properties
- 关于计算机哪些学校好,计算机哪些学校好
- 分区桌面 壁纸(正在做,常用,之后在做,临时存)
- pic pwm 占空比可调 源码_PWM占空比 调节实例
- UNI-APP在iOS系统中加载来源于微信公众号的文章时(html片段),某些图片显示不出来的问题解决
- 淘宝天猫店铺微信公众平台建设指南
- 重装 UOS Deepin V20 后必安装软件(个人习惯)
- PS制作文字扫描效果(仿旧效果)
- from_unixtime()与UNIX_TIMESTAMP
- excel表格分割线一分为二_Anki+思维导图的两种方法(Anki+表格,Anki+幕布)
- C学习笔记——(4)数组和字符串说明,以及冒泡排序法
- EasyExcel工具类封装, 做到一个函数完成简单的读取和导出
- html5核心ml5图片居中,HTML5图片居中的问题
- 利用dlib81人脸关键点提取额头脸颊ROI
- Vision Transformer 综述
- Excel输出随机小数的方法