1.分组
在正则表达式中还提供了一种将表达式分组的机制,当使用分组时,除了获得整个匹配。还能够在匹配中选择每一个分组。
要实现分组很简单,使用()
即可。
捕获分组
分组有一个非常重要的功能——捕获数据。所以()
被称为捕获分组,用来捕获数据,当我们想要从匹配好的数据中提取关键数据的时候可以使用分组。
<div>(.*?)</div>
可以提取两个div中间的数据。
(\d+)\D(\d+)\D(\d+)
可以提取日期信息 YYYY-mm-dd
使用或条件
使用分组的同时还可以使用 或者(or)条件。
例如要提取所有图片文件的后缀名,可以在各个后缀名之间加上一个 |
符号:
.+(.mp4|.avi|.wmv|.rmvb)
可以匹配结尾为指定格式的数据
非捕获分组
有时候,我们并不需要捕获某个分组的内容,但是又想使用分组的特性。
这个时候就可以使用非捕获组(?:表达式)
,从而不捕获数据,还能使用分组的功能。
例如想要匹配两个字母组成的单词或者四个字母组成的单词就可以使用非捕获分组:
\b(?:\w{2}|\w{4})\b
可以匹配指定的单词
eg:现在我们想要使用正则表达式将其中的年月日全都提取出来
可以发现他们唯一的区别就在于分隔符和月份与日期,这个时候可以使用[]
来匹配多种情况。
20200102
2020-01-02
2020-1-2
2020.01.02
2020 01 02
2020 1 2
2020/01/02
(\d{4})[-./\s]?(\d{1,2})[-./\s]?(\d{1,2})
可以从文本中将年月日分别提取出来了。
虽然这段正则表达式看起来内容挺多,但是还是很容易理解的,[-./\s]
表示匹配三个可能出现的分隔符-./
和空白,?
表示匹配它们0次或者1次,其他年月日的数据使用\d{N}
与分组结合就可以提取到目标数据。
注意:因为正则表达式中
()
代表分组,所以如果要匹配()
就需要将使用转义符\
,例如要匹配)
就要写成\)
。
分组的回溯引用
正则表达式还提供了一种引用之前匹配分组的机制,有些时候,我们或许会寻找到一个子匹配,该匹配接下来会再次出现。使用\N
可以引用编号为N
的分组即为分组的回溯引用。
<\(w+)>.*?</\1>
可以用来匹配一对正确的html 标签
(\w)(\w)\2\1
可以匹配 abba 类似关系的单词
2.先行断言
正向先行断言
很多人也称先行断言和后行断言为环视,也有人叫预搜索。
正向先行断言:(?=表达式)
,指在某个位置向右看,表示所在位置右侧必须能匹配表达式
eg :
我喜欢你 我喜欢 我喜欢我 喜欢 喜欢你
如果要取出喜欢两个字,要求这个喜欢后面有你,这个时候就要这么写:喜欢(?=你)
,这就是正向先行断言。
可以匹配到我喜欢你 喜欢你
eg :现在请你编写正则表达式进行密码强度的验证,规则如下:
至少一个大写字母
至少一个小写字母
至少一个数字
至少8个字符
左边为需要你的正则需要匹配的,右边的字符串是你的正则不需要匹配的。
可以使用.*((?=.*[A-Z]).*(?=.*[a-z]).*(?=.*[0-9])).{8,}
做到
反向先行断言
反向先行断言(?!表达式)
的作用是保证右边不能出现某字符。
eg : 编写正则表达式匹配不是qq邮箱的数据。
.
@(?!qq)
表达式即可实现
3.后行断言
正向后行断言
先行断言和后行断言只有一个区别,即先行断言从左往右看,后行断言从右往左看。
正向后行断言:(?<=表达式)
,指在某个位置向左看,表示所在位置左侧必须能匹配表达式
eg:如果要取出喜欢两个字,要求喜欢的前面有我,后面有你,这个时候就要这么写:
(?<=我)喜欢(?=你)
反向后行断言
反向后行断言:(?<!表达式)
,指在某个位置向左看,表示所在位置左侧不能匹配表达式
eg:如果要取出喜欢两个字,要求喜欢的前面没有我,后面没有你,这个时候就要这么写:
(?<!我)喜欢(?!你)
正则基础语法可以参考 正则30分钟入门视频