概述
前向断言
- 0 断言
- 1 前向肯定断言
- 1.1 语法
- 1.2 示例
- 1.3 其他示例
- 2 前向否定断言
- 2.1 语法
- 2.2 示例
- 2.3 其他示例
0 断言
你将从本文中学到正则表达式里的前向肯定断言和前向否定断言,包括它们的语法和示例。
前向断言对于构造一个实用的正则表达式来说非常重要,它是周围断言的其中一(另一种是后向断言)。
断言分两个方向:前和后。所谓前向是指我们书写的方向,从左往右写的话就是右向,与前向相反的方向就是后向。
前向断言,顾名思义,就是看看我们匹配项前面的元素是否满足某条件,满足的话就说明这个匹配项是真的匹配,于是返回这个匹配项,否则就说明这是假匹配,那么就不返回此匹配项。
看到这里,读者也许会思考,这和普通的正则项有啥不同呢?为啥非得另起别名呢?
有不同!且不同有二:
- 一是普通的正则项在结果中有对应的字符串,参与匹配项的提取,即会被捕获,断言则不被捕获,即不进入最终匹配结果;
- 二是断言的位置固定,前向断言只用于整个正则式的末尾,后向断言则只用于整个正则式的起始。
看到这里,又有疑问了,断言和泊点 ^
和 $
的用法不就一样了吗?是的!它们的用法很相似!只是要所用场景稍有不同,^
和 $
卡匹配串的首尾为字符串的头尾,而断言则卡匹配串的首尾须满足所给条件。
某些参考文献中将
lookahead assertion
翻译为 “正向预查”,正向与前向之辩无谓,但“预查”使用不当。预是预先的意思,预查很容易理解成预先查找,也就是先查找前向表达式,而后进行主匹配项查找。实际上这是不对的,lookahead assertion
不是预先进行的查找的,而是指在找到位于它前面的匹配项之后对接下来的元素进行断言,也就是看看满不满足我们的条件,其中的元素也不是查找的对象,而是用于判断匹配是否成功,并不进入要返回的匹配结果。
1 前向肯定断言
对于这种断言,正则表达式引擎会在找到匹配项后寻找满足断言条件的特定字符或字符串或组(圆括号所包围的项 (...)
)。若条件满足,则声明此匹配项有效,否则拒绝此匹配项。
1.1 语法
match(?=elem)
其中,match
表示我们想要匹配并返回的字符串的模式; elem
表示前向断言元素,element 的缩写。
若我们找到的与 match
匹配的字符串后紧跟元素 elemt
,则匹配才真正成功;否则匹配失败。
前向断言属于组的一种,即由圆括号包裹的一个子表达式,子表达式以问号 ?
起始,等号 =
紧随其后,接着是要查看的元素。
我们定义我们书写顺序的前方,即 x x x 轴正方向为正向;定义我们书写顺序的后方,即 x x x 轴负方向为反向。正向断言就是向前(ahead)看是否满足我们的条件;反向断言就是向后(behind)看是否满足我们的条件。
1.2 示例
现有表达式:a(?=b)
,它会匹配一个后跟 b
的 a
,即能匹配 ab
、abc
、abz
,但不能匹配 ba
、bax
、ca
等。
现在让我们研究下在执行该断言时正则引擎是怎么做的。
测试串:This is a car
正则式:a(?=r)
此正则式将会匹配后紧跟一个 r
的 a
。
- 首先,正则引擎会在字符串里从左向右寻找
a
, 于是找到第一个紧跟is
的a
; - 匹配到
a
后,引擎进入组,遇到符号?=
,于是知道组内是一个前向肯定断言; - 接着,引擎看匹配到的
a
的后面是否紧跟元素r
,发现是空格而非
r
,条件不满足,断言失败,引擎接着往前(右)走寻找下一个a
; - 引擎找到了紧跟
c
的a
。 - 匹配到
a
后,引擎再一次进入组,并知道这是一个前向肯定断言; - 接着引擎看匹配到的
a
的后面是否紧跟元素r
,发现是,条件满足,断言成功。 - 返回此匹配项 ‘a’。
1.3 其他示例
想匹配:后缀有字符 'a'
的字符串中的 "I love China"
子串,即 "I love Chinaa"
中 "I love China"
子串
不想匹配:未后跟字符 'a'
的字符串中的 "I love China"
子串,如 "I love Chinab"
、"I love Chinac"
中的 "I love China"
子串
正则式:"I love China(?=a)"
2 前向否定断言
对于这种断言,正则表达式引擎会在找到匹配项后寻找满足断言条件的特定字符或字符串或组(圆括号所包围的项 (...)
)。若条件满足,则声明此匹配项有效,否则拒绝此匹配项,与上面的肯定断言不同,这里的条件是否定的。
2.1 语法
match(?!elem)
若我们找到的与 match
匹配的字符串后紧跟的元素不是 elemt
,则匹配才真正成功;否则匹配失败。
其中,match
表示我们想要匹配并返回的字符串的模式; elem
表示前向断言元素,是元素 element 的缩写,只有当紧跟 match
的元素不是 elem
时才是一个成功的匹配。
a(?!b)
可匹配所有后跟元素不是 b
的 a
,如 ac
、ad
、az
,但不会匹配 ab
、abc
。
2.2 示例
测试串: The number of car sold is larger than car not sold and car being repaired
正则式:car(?!s+sold)
该正则式会匹配出已售状态(sold)外所有其他状态的车(not sold、being repaired)。
通过前向否定断言,你就可以找到那些没有后跟某些元素的匹配项。
2.3 其他示例
想匹配:为后跟字符 'b'
的字符串中的 "I love China"
子串,如 "I love Chinaa"
、"I love Chinac"
不想匹配:后缀以字符 ' b'
的字符串中的 "I love China"
子串,如 "I love Chinab"
正则式:"I love China(?!b)"
最后
以上就是传统石头为你收集整理的前向断言/前向预查/正向断言/正向预查(lookahead assertions)0 断言的全部内容,希望文章能够帮你解决前向断言/前向预查/正向断言/正向预查(lookahead assertions)0 断言所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复