正则表达式分组、断言详解
正则表达式分组、断言详解
正则表达式分组,断言详解
举个例子
比如要抓取到 html 源码里的 <title>xxx</title>
, 里面的 xxx。按照基本的操作,只能 <title> .*</title>
而这样写匹配出来的是完整的<title>xxx</title>
标签,并不是单纯的页面标题 xxx。
想解决以上问题,就要用到断言知识。
在讲断言之前,读者应该先了解分组,这有助于理解断言。
分组在正则中用()
表示,分组的作用有两个:
- 将某些规律看成是一组,然后进行组级别的重复,可以得到意想不到的效果。
- 分组之后,可以通过后向引用简化表达式。
继续举例子
在匹配 ip 地址时,我们可以这样写
1 |
|
发后面重复,利用分组,我们可以这样简写
1 |
|
然后我们再利用分组的做法,优化哈上个例子
普通写法
1 |
|
使用分组简写
1 |
|
说明:这里
\1
叫反向引用 其实是引用了第一个括号中里也就是第一个分组里的文本内容
。整正则式子默认为第 0 组,而第一个小括号扩住的分组就是第一组,依次类推。通过\index
引用某组的文本内容
, 切记 引用的不是正则表达式,而是匹配的文本结果
然后我们再使用反向引用,来匹配哈上面的 ip 地址
简化后如下
1 |
|
解释:把 \d{1,3}
成组,, 再通过 \1
引用该分组,在对此引用连续匹配 3 次。
但是这样写是错误的 ❌
这样匹配的 ip 每一段都是相同的,比如 123.123.123.123
因为 后向引用,引用的仅仅是文本内容,而不是正则表达式!
然后继续说 断言
所谓断言,多用于匹配,没有什么规律的文本,通过匹配他的前后文,反推出它来。
即通过判断 需匹配文本 的前边或后边,将会出现满足某种规律的字符串。**并且断言只是条件,帮你找到真正需要的字符串,本身并不会匹配!也没有编号,所以不能用来后向引用**
符号 | 描述 |
---|---|
?= | 正先行断言-存在 |
?! | 负先行断言-排除 |
?<= | 正后发断言-存在 |
?<! | 负后发断言-排除 |
就拿文章开篇的例子来说,我们想要的是xxx,它没有规律,但是它前边肯定会有`<title>`,后边肯定会有`</title>`,这就足够了。
想指定 xxx 前肯定会出现<title>
,就用正后发断言,表达式:(?<=<title>).*
向指定 xxx 后边肯定会出现</title>
,就用正先行断言,表达式:.*(?=</title>)
两个加在一起,这样就能匹配到 xxx。
1 |
|
无论正先行断言还有正后发断言,都是相对需匹配的文本(上文的 xxx)判断的。
也就是说,断言的名称,正先行还是正后发,即是相对
匹配目标
而定的。如果匹配目标后边有条件,也就是目标字符串在前,即使用正先行断言 ?=
如果匹配目标前边有条件,也就是目标字符串在后,即使用正后发断言 ?<=
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!