向前看一眼
正向先行断言写在当前位置,检查右边是否满足某个条件,检查完位置不前进,被检查的内容也不会出现在结果里。它相当于给当前位置加一条附加条件:条件成立就继续,不成立就换位置。
组合条件的能力
因为断言不消耗字符,可以把多个断言并排叠加在同一个位置上,表达「后面既要满足 A 又要满足 B」。这是用正则做密码复杂度、格式多重约束校验的常见手法。
基本信息
| 写法 | 圆括号内以问号等号开头,后面写条件子模式 |
|---|---|
| 宽度 | 零宽,不消耗字符,不影响匹配结果内容 |
| 方向 | 只检查右侧内容 |
| 可叠加 | 多个断言可并排写在同一个位置,形成「与」关系 |
| 可含捕获 | 部分引擎允许断言内部使用捕获分组,会占用组编号 |
| 引擎支持 | PCRE、Python、Java、.NET、JavaScript 支持;无回溯引擎通常不支持 |
典型使用场景
- 密码复杂度校验:同时要求含字母、数字、符号且长度达标
- 要求右边必须出现某个字符但又不把它纳入匹配结果
- 在替换时按后续内容决定是否替换,例如只替换后面跟分号的行
- 约束数字后面不能紧跟小数点,区分整数与浮点表示
- 提取内容并按后续上下文过滤
先行断言的写法
先行断言的写法
^(?=.*[a-z])(?=.*\d)(?=.*[^A-Za-z0-9]).{8,}$ # 三类字符都出现且长度足够
foo(?=\d) 其后必须是数字,但数字不进入匹配结果
\d+(?=\.) 只在后面跟点号时匹配数字(取整数部分)
(?=(?:.*\d){2}) 要求右侧至少出现两位数字
(?=.*\badmin\b) 位置无关的存在性检查
# 断言不消耗字符:匹配结果里看不到被检查的内容断言类型速查
| 写法 | 含义 | 方向 |
|---|---|---|
| 问号等号开头 | 必须满足后面条件 | 向右 |
| 问号感叹号开头 | 必须不满足后面条件 | 向右 |
| 问号小于等于开头 | 必须满足前面条件 | 向左 |
| 问号小于感叹号开头 | 必须不满足前面条件 | 向左 |
| 单词边界 | 位置条件,本质也是零宽断言 | 双向 |
多个断言串在同一个位置时,它们之间是「且」的关系,按任意顺序写结果相同。若需要「或」,把分支写在断言内部,或分别列出完整模式。
断言内部的子模式同样会参与匹配尝试,写得宽泛同样可能带来回退压力。在断言里使用点号重复时,应尽量收窄范围。