正则表达式的先行断言和后行断言一共有4种形式:
| 格式 | 中文名称 | 英文名称 |
| ?=pattern | 零宽正向先行断言 | zero-width positive lookahead assertion |
| ?!pattern | 零宽负向先行断言 | zero-width negative lookahead assertion |
| ?<=pattern | 零宽正向后行断言 | zero-width positive lookbehind assertion |
| ?<!pattern | 零宽负向后行断言 | zero-width negative lookbehind assertion |
名词释义
- 零宽(
zero-width)
见文知义,零宽表示一种零宽度的匹配,它匹配到的内容不会保存到匹配结果中去,最终匹配结果只是一个位置而已。 - 正向(
positive)和负向(negative)
不等于(!=)、逻辑非(!)都是用!号来表示,所以有!号的形式表示不匹配、负向
将!号换成=号,就表示匹配、正向 - 先行(
lookahead)和后行(lookbehind)
正则表达式引擎在执行字符串和表达式匹配时,会从头到尾(从前到后)连续扫描字符串中的字符,设想有一个扫描指针指向字符边界处并随匹配过程移动。
先行断言,是当扫描指针位于某处时,引擎会尝试匹配指针还未扫过的字符,先于指针到达该字符,故称为先行。
后行断言,引擎会尝试匹配指针已扫过的字符,后于指针到达该字符,故称为后行。
含义
( ?=pattern ) 正向先行断言
代表字符串中的一个位置, 紧接该位置之后 的字符序列 能够匹配pattern。
例如对” a regular expression ”这个字符串,要想匹配 regular 中的 re ,但不能匹配 expression 中的 re ,可以用” re(?=gular) ”,该表达式限定了 re 右边的位置,这个位置之后是 gular ,但并不消耗 gular 这些字符,将表达式改为” re(?=gular). ”,将会匹配 reg , 元字符. 匹配了 g ,括号这一砣匹配了 e 和 g 之间的位置。
( ?!pattern ) 负向先行断言
代表字符串中的一个位置, 紧接该位置之后 的字符序列 不能匹配pattern。
例如对” regex represents regular expression ”这个字符串,要想匹配除 regex 和 regular 之外的 re ,可以用” re(?!g) ”,该表达式限定了 re 右边的位置,这个位置后面不是字符 g 。
负向和正向的区别,就在于该位置之后的字符能否匹配括号中的表达式。
( ?<=pattern ) 正向后行断言
代表字符串中的一个位置, 紧接该位置之前 的字符序列 能够匹配pattern。
例如对” regex represents regular expression ”这个字符串,有4个单词,要想匹配单词内部的 re ,但不匹配单词开头的 re ,可以用” (?<=\w)re ”,单词内部的 re ,在 re 前面应该是一个单词字符。
之所以叫后行断言,是因为正则表达式引擎在匹配字符串和表达式时,是从前向后逐个扫描字符串中的字符,并判断是否与表达式符合,当在表达式中遇到该断言时,正则表达式引擎需要往字符串前端检测已扫描过的字符,相对于扫描方向是向后的。
(?<!pattern) 负向后行断言
代表字符串中的一个位置, 紧接该位置之前 的字符序列 不能匹配pattern。 例如对” regex represents regular expression ”这个字符串,要想匹配单词开头的 re ,可以用” (?<!\w)re ”。单词开头的 re ,在本例中,也就是指不在单词内部的 re ,即 re 前面不是单词字符。当然也可以用” \bre ”来匹配。