浅谈正则表达式的断言

1,626 阅读1分钟

这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战

浅谈正则表达式的断言

简介

正则表达式的断言 assertion,也称作零宽断言 zero-width assertion

  • 零宽 zero-width,指的是它只匹配位置,不匹配字符,也就不占据任何宽度。这有点类似行首 ^ 和行尾 $ 以及单词边界 \b 这些锚点 anchor
  • 断言 assertion,指在匹配的过程中,会放弃匹配到的内容,只返回两个结果:匹配成功和匹配失败。所以它不消耗待搜索字符串中的任何字符。
  • 断言可以分为正向 positive 和负向 negative
    • 正向:表示期望待搜索字符串中存在断言
    • 负向:表示期望待搜索字符串中不存在断言
  • 匹配也是有查找方向的,即先行断言和后行断言,两者统称为环视断言 lookaround assertion
    • 向右匹配,或者说向前匹配,是先行 lookahead
    • 向左匹配,或者说向后匹配,是后行 lookbehind

四种形式

正则表达式的断言有四种形式:

  • 零宽正向先行断言 zero-width positive lookahead assertion,简称正向先行断言,语法:(?=pattern)
  • 零宽负向先行断言 zero-width negative lookahead assertion,简称负向先行断言,语法:(?!pattern)
  • 零宽正向后行断言 zero-width positive lookbehind assertion,简称正向后行断言,语法:(?<=pattern)
  • 零宽负向后行断言 zero-width negative lookbehind assertion,简称负向后行断言,语法:(?<!pattern)

实例

假设现在有一个需求,在注册用户的时候,需要验证用户的密码必须包含英文大小写字母以及数字,则可以使用下面的正则表达式:

  • (?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).*

(?=.*[a-z]) 是一个正向先行断言,用于判断在任意字符(包括没有字符的情况)后面是否出现了小写英文字母。这个断言不匹配具体内容,所以后面可以继续使用 (?=.*[A-Z])(?=.*[0-9]) 分别断言待搜索字符串中包含大写字母以及数字。另外在最后加上 .* 可以匹配到用户输入的密码。

工具分享

分享几个在线测试正则表达式的工具: