正则表达式之零宽断言

本篇文章提到的零宽断言是正则表达式高级语法,阅读此文需要有一定的正则表达式基础。

关于断言

断言(assertion)在正则表达式里面有着举足轻重的作用。通常情况下指的是在目标字符串的当前位置进行的一种判断测试,但这种测试不会占用目标字符串,这意味着不会移动目标字符串在当前匹配中的位置。

断言元字符

最常用的两个断言元字符是^$,它们分别表示字符串开始和字符串结束。

其他一些断言元字符参见下表:

  • \b,单词分界符
  • \B,非单词分界符
  • \A,字符串的开头,忽略multiline标识
  • \Z,字符串的结尾或者字符串结尾的换行符\n之前,忽略multiline标识
  • \z,字符串的结尾,忽略multiline标识
  • \G,字符串的第一个位置

\A\Z\z\G很少使用。

捕获与非捕获组

非捕获组(?:pattern)不是本文的知识点,这里不做详细讲解,文章后面有参考资料可自行参阅。

零宽断言

断言元字符通常是基于当前位置的测试,断言也可以支持更加复杂的判断条件。更复杂的断言以子模式来进行表示,包括先行断言和后行断言。两者都是本文要解说的零宽断言

同断言元字符一样,零宽断言的判断匹配只做条件匹配,不会记录匹配结果,也不会匹配字符。

零宽正向先行断言

  • 英文:zero-width positive lookahead assertion
  • 简称:positive lookahead
  • 语法:(?=pattern)
  • 概述:从当前位置开始测试后面的字符串匹配pattern,仅当右侧匹配成功时才继续。
  • 举例:[a-zA-Z]+(?=\d),匹配一个后面跟着数字的字母,但匹配结果不包含该数字。

零宽负向先行断言

  • 英文:zero-width negative lookahead assertion
  • 简称:negative lookahead
  • 语法:(?!pattern)
  • 概述:从当前位置开始测试后面的字符串不匹配pattern,仅当右侧不能匹配时才继续。
  • 举例:使用正则表达式re(?!g),匹配字符串regular expression,则regular中的_re_不会被匹配,expression中的_re_将会被匹配。

零宽正向后行断言

  • 英文:zero-width positive lookbehind assertion
  • 简称:positive lookbehind
  • 语法:(?<=pattern)
  • 概述:从当前位置开始测试前面的字符串匹配pattern,仅当左侧匹配成功时才继续。

零宽正向后行断言

  • 英文:zero-width negative lookbehind assertion
  • 简称:negative lookbehind
  • 语法:(?<!pattern)
  • 概述:从当前位置开始测试前面的字符串不匹配pattern,仅当左侧不能匹配时才继续。

注意:后行断言由于存在回溯情况,JavaScript没有对其进行实现

为什么 JavaScript 的正则不支持 “零宽度正回顾后发断言” ?

参考资料