正则表达式中有前瞻(Lookahead)和后顾(Lookbehind)的概念,这两个术语非常形象的描述了正则引擎的匹配行为。需要注意一点,正则表达式中的前和后和我们一般理解的前后有点不同。一段文本,我们一般习惯把文本开头的方向称作“前面”,文本末尾方向称为“后面”。但是对于正则表达式引擎来说,因为它是从文本头部向尾部开始解析的(可以通过正则选项控制解析方向),因此对于文本尾部方向,称为“前”,因为这个时候,正则引擎还没走到那块,而对文本头部方向,则称为“后”,因为正则引擎已经走过了那一块地方。如下图所示:

所谓的前瞻就是在正则表达式匹配到某个字符的时候,往“尚未解析过的文本”预先看一下,看是不是符合/不符合匹配模式,而后顾,就是在正则引擎已经匹配过的文本看看是不是符合/不符合匹配模式。符合和不符合特定匹配模式我们又称为肯定式匹配和否定式匹配

现代高级正则表达式引擎一般都支持都支持前瞻,对于后顾支持并不是很广泛,因此采用否定式前瞻来实现。

前瞻(正向预测先行搜索(向前)、正向肯定预查) lookahead (?=在这里编写内容)没有指示符表示方向向右,即向前
后顾(正向预测后行搜索(向后)、反向肯定预查) lookbehind (?<=在这里编写内容)“<”表示方向向左,即向后。
负前瞻(反向预测先行搜索、正向否定预查) negative lookahead (?!在这里编写内容),没有指示符表示方向向右,即向前。
负后顾(反向预测后行搜索、反向否定预查) negative lookbehind (?<!在这里编写内容),“<”表示方向向左,即向后。

前瞻和后顾合称瞻前顾后、左顾右盼、东张西望 lookaround

后顾功能在大多数语言中有长度限制,而且只能使用定长的表达式,像\w+和\d?这样的表达式长度可变,用在后顾功能中属于语法错误,实际上不是语法错误,是正则表达式本身太扯淡,软件没实现这个功能,不让你用罢了。

Java对后顾功能的支持度,可以用?符号了,不能用+号,因为+号实在太扯淡,能匹配一个字符,也能匹配一万个字符,人家Sun公司的码农根本实现不出来,所以不给你提供这个功能。

.NET对后顾功能的支持度最高,可以匹配可变长度字符,可以用+号了,不愧是世界首富比尔盖茨微软,多砸钱,不信有实现不出来的功能。

注意:正则表达式匹配属于按字符从左到右匹配,而不是按多个字同时匹配。先匹配第一个字符,如果能匹配成功,则匹配第二个字符,依次类推……

总之,使用后顾的时候小心,不要写得天花乱坠,啥符号都往里塞。

更多推荐

正则表达式前瞻后顾