一直以来,使用正则表达式的机会不少,经常用来做一些字符串处理工作,还是比较方便的,不过对于断言和贪婪懒惰模式的认识一直比较模糊。最近我们后端组在协作开发一个对外的后台项目,前端的接口文档是用word写了(汗-_-||,很难用啊,还是markdown比较好)里面有一个接口列表的表格,这里的接口列表需要提取出来,形成一个权限链路做权限控制,减少ajax的RBAC权限配置的臃肿。这里我用了正则表达式来完成,做完之后我对正则表达式的理解和使用也算是小成了,下面我就说一下正则表达式几种常见用法我的理解。
网上有《正则表达式30分钟入门教程》珠玉在前,基础知识我就不多说了,大家自己去看。
分组
1、对于一些有一定模式或者以一定规律出现的字符串,我们想要匹配并且捕获到它们;
2、这些字符串我们不但要匹配捕获到它们,还要向后引用进行例如替换之类的处理;
正则表达式中分组的单位用(exp)小括号来区分,里面exp就是要匹配的内容。
匹配ip地址xxx.xxx.xxx.xxx可以写成以下形式
\d{1,3}(\.\d{1,3}){3}
匹配少数民族的真实姓名
[\x{4e00}-\x{9fa5}]+(·[\x{4e00}-\x{9fa5}]+)*
(此处贴个毕加索的全名。。。[巴勃罗·迭戈·荷瑟·山迪亚哥·弗朗西斯科·德·保拉·居安·尼波莫切诺·克瑞斯皮尼亚诺·德·罗斯·瑞米迪欧斯·西波瑞亚诺·德·拉·山迪西玛·特立尼达·玛利亚·帕里西奥·克里托·瑞兹·布拉斯科·毕加索])
而正则表达式中默认第0个分组是匹配到整条正则表达式的字符串
分组命名
我们还可以给分组进行命名,方便区分
(?<name>exp)
匹配到exp的内容就会捕获到一个命名为name的分组里面,不影响原来的索引分组情况,也可以写成
(?'name'exp)
在向后引用中,我们可以使用 \n 或者 $n 来引用匹配到的分组内容,即第n个出现的小括号。
不捕获
在正则表达式中,我们可以选择关闭对不需要的内容的捕获,就是不捕获,以此来提高正则表达式的执行速度和节约内存使用。
语法是:
(?:exp)
零宽断言
零宽,顾名思义,就是没有宽度,匹配到的字符串不会被捕获。
断言,就是true or false。
下面是4种断言的说明:
名称 | 语法 | 说明 |
---|---|---|
零宽度正先行断言 | (?=exp) | 匹配到exp则停止 |
零宽度负先行断言 | (?!exp) | 匹配不到exp则停止 |
零宽度正后发断言 | (?<=exp) | 匹配到exp则继续 |
零宽度负后发断言 | (?<!exp) | 匹配不到exp则继续 |
ps:千万傻傻别去的记名称,理解用法最重要
零宽断言只是用来判断是否符合继续匹配的条件,并不会找到真正需要的字符串,本身并不会匹配字符
例如,在爬虫中我们可能需要匹配某些图片url,我们就可以用断言来获取图片url。
贪婪和懒惰模式
正则表达式中默认的行为是在整个表达式能够匹配的前提下,匹配尽可能多的字符,这称之为贪婪模式。
不过有时候,我们还在整个表达式匹配的前提下尽可能少的匹配字符,这就需要用到懒惰模式了。
懒惰模式的语法也简单,只需要在你所需匹配的字符后面再加一个?即可。
语法 | 说明 |
---|---|
*? | 重复任意次,但尽可能少重复 |
+? | 重复1次或更多次,但尽可能少重复 |
?? | 重复0次或1次,但尽可能少重复 |
{n,}? | 重复n次以上,但尽可能少重复 |
解释:懒惰模式就是在你设想字符可能出现的次数中,尽可能匹配少的次数。
以上就是正则表达式的分组,零宽断言和贪婪懒惰模式的讲解,下期再见。