正则表达式的先行断言和后行断言一共有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
”来匹配。