正则表达式之分组捕获和位置指定
一、问题背景
相信大家在学习正则表达式的时候一定会对分组捕获和位置指定非常懊恼,不知道怎么去记,而不会记混。我也是熬了一个多小时,总结出来一个小技巧。
二、分析思路
- 任何语法的出现都是为了实现某一目标(剩下的就是需要我们去理解,如果要实现目标,一般怎么做比较合理);
- 目的 --> 实现方法;
- 所有语法都是人定的,必然符合大部分人理解的逻辑;
三、记忆技巧
分组匹配
- 需求1
在一次匹配搜索中,后面需要使用前面的匹配到的结果,比如
I love the world, and love everything.
Reg: I love\b[ a-z,]+love[a-z \.]+
显然上面的整个正则表达式有点臃肿,不够简洁,其中love就重复了。
- 如何优化呢?
分组匹配就派上用场了,前面已经匹配了一次love(love是最简单的正则表达式,也可以是其他更复杂的表达式)。我们把前面匹配的结果缓存起来,下次就可以直接拿来用。作者的语法形式就是使用(),将love包裹起来,后面需要使用的地方就有\n,这里的n是子表达式的顺序,这个顺序就不详细解释,大家自己可以尝试着写写。
优化后的正则表达式如下:
Reg: I **(love)**\b[ a-z,]+**\1**[a-z \.]+
- 需求2
通常我们都是在代码中使用分组捕获,使用\n来重复利用前面的匹配结果,意义不明 - 如何优化?
引入(?love) 替代(love),我们在获取这个匹配分组的结果时,就可以直接从分组name中获取。 - 需求3
想匹配分组的子字符串,但是又不想缓存 - 如何实现呢?
(?:reg)
这个没有诀窍,多多练习,直接记住吧,哈哈哈哈哈哈哈哈哈。
非捕获匹配
- 需求1
只想搜索我们需要的字符串,我们通常会看我们期望的字符串旁边的信息,但是我们又不想要前后的信息,前后的信息只是用来定位。
前后的信息,我们可能需要,“不包含xxx”、“包含xxx”等需求。- 如何优化呢?
思路很清晰,用前后的信息来辅助匹配,官方的语法为
- 如何优化呢?
# 匹配 str后面为正则表达式匹配为reg的 字符串
str<?=reg>
上面有一个地方非常非常重要,str才是我们想要搜寻的字符串,reg只是用来定位副歌条件的字符串,弄清楚这个之后,再看?=和?!,都是基于我们目标字符串str,说的是str后匹配reg,不匹配reg。至于<,知道了正常人理解的顺序后,这个就是反过来匹配了。
然后,大家再去理解经常搜到的一下“xxx前xxx”、“xxx后xxx”…之类的,是不是就不那么头晕了。
(?=exp) 匹配exp前面的位置
(?<=exp) 匹配exp后面的位置
(?!exp) 匹配后面跟的不是exp的位置
(?<!exp) 匹配前面不是exp的位置
- 需求2