正则表达式的解读方法
读者最好能养成按照字符来理解正则表达式的习惯。(参考自动物书《精通正则表达式》,这种读法对我来说更好理解,且更容易举一反三)
错误解读方式:「^cat」匹配以cat开头的行
推荐解读方式:「^cat」匹配的是以c作为一行的第一个字符,紧接一个a,紧接一个t的文本。
符号概念
符号 | 概念 |
---|---|
* | 通配符:任意个(0/n) |
+ | 通配符:非零个(1/n) |
? | 通配符:可选项(0/1) |
. | 任意字符:可以代表任意字符 |
^ | 起始符号:该符号后的字符必须是开头 |
$ | 截止符号:该符号前的字符必须是结尾 |
{n,m} | 数量限制:限制字符的数量时n~m |
[0-9a-zA-Z_] | 字符组:选择括号内任意一个字符, ^在字符组[ ]里为非的意思,[ ^a ]意指非a字符, -在字符组[ ]表示一个范围,[0-9]表示0到9数字里的任意一个数字 |
\d\D | 数字字符/非数字字符 |
\w\W | 数字字母下划线/非数字字母下划线 |
\s\S | 空格制表换行符…/非空格制表换行符… |
? | 非贪婪:re默认贪婪匹配,加?后变非贪婪 |
() | 组:对匹配分组 |
| | 或:连接多个正则表达式 |
练习的网站
看两个现象进行后续思考
可以看到返回结果里有一个符合条件的结果,Match 1 ,
那么剩下的三个Group是什么呢
为什么是按415,555,4242这样去分三组呢(聪明的你也行会猜到是根据表达式里的()进行划分的)
那么接着看下一个现象
在括号(\d{3})里加上?:,发现匹配返回的组少了一组 555
还是聪明的你应该又猜到了?:的作用就是不让()内的匹配内容出现在Group里,
(悄悄告诉你这就是传说中的非捕获,非捕获可以简单理解为不让匹配的内容出现在Group里)
你大声说:那么出现在Group里的就是捕获!
恭喜抢答成功,那么下面就来介绍与捕获和非捕获相关的正则表达
Group的用途
业务上,获取到想要的某组内容后,可以对每个捕获的组的数据做自定义的操作
捕获组和非捕获组
捕获组
每个捕获组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。
非捕获组
- (?:pattern) : 匹配pattern,但不捕获匹配结果。e.g.:
industr(?:y|ies)
可以匹配到'industry'或'industries'
- (?=pattern): 零宽度正向预查(正向零宽断言),匹配后面跟的是pattern的内容,不匹配pattern,也不捕获匹配结果。e.g.
Windows(?=95|98|NT|2000)
能匹配到"Windows2000" 中的 "Windows"
不能匹配到 "Windows3.1" 中的 "Windows"
- (?!pattern): 零宽度负向预查(负向零宽断言),匹配后面跟的不是pattern的内容,不匹配pattern,不捕获匹配结果。e.g.:
Windows(?!95|98|NT|2000)
能匹配 "Windows3.1" 中的 "Windows"
不能匹配 "Windows2000" 中的 "Windows"
- (?<=pattern): 零宽度正向回查(正向零宽断言),匹配前面是pattern的内容,不匹配pattern,不捕获匹配结果。e.g.
(?<=Office|Word|Excel)2000
能匹配 " Office2000" 中的 "2000"
不能匹配 "Windows2000" 中的 "2000"
- (?<!pattern): 零宽度负向回查(负向零宽断言),匹配前面不是pattern的内容,不匹配pattern,不捕获匹配结果。e.g.:
(?<!Office|Word|Excel)2000
能匹配 " Windows2000" 中的 "2000"
不能匹配 " Office2000" 中的 "2000"
组的命名
(?pattern)或(?'name’pattern) : 匹配pattern并捕获结果,设置name为组名。