正则表达式前瞻匹配(零宽度先行断言)
基于 ECMAScript 正则表达式语法
断言不消耗输入中的任何字符,仅判断当前位置是否满足某种条件。例如 ^ 和 $ 分别断言文本的开头和结尾,本身不匹配任何字符。
零宽度正向先行断言
(?=...):当前位置之后的文本能够匹配...时,断言成功。
示例一:(?=(a+))a*b 匹配 baaba
- 位置 0(
b):a+无法匹配,失败。 - 位置 1(
a):a+贪婪匹配aa(位置 1–2),断言成功,当前位置仍在 1。继续匹配a*b:a*贪婪匹配aa(位置 1–2),b匹配位置 3 成功。 - 最终匹配
aab(位置 1–3),分组 1 捕获aa。
示例二:(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).{6,} 匹配 abc2ABC
要求包含小写字母、大写字母和数字,且长度至少为 6。依次执行三个前瞻断言(均从位置 0 开始):
(?=.*[a-z]) — 是否包含小写字母
.*贪婪匹配全部 7 字符,[a-z]无剩余可匹配,失败。- 回溯至 6 字符:剩
C,[a-z]失败。 - 回溯至 5 字符:剩
B,失败。 - 回溯至 4 字符:剩
A,失败。 - 回溯至 3 字符:剩
2,失败。 - 回溯至 2 字符:剩
c,[a-z]匹配成功。
(?=.*[A-Z]) — 是否包含大写字母
.*贪婪匹配全部 7 字符,[A-Z]失败。- 回溯至 6 字符:剩
C,[A-Z]匹配成功。
(?=.*[0-9]) — 是否包含数字
.*贪婪匹配全部 7 字符,[0-9]失败。- 回溯至 6 字符:剩
C,失败。 - 回溯至 5 字符:剩
B,失败。 - 回溯至 4 字符:剩
A,失败。 - 回溯至 3 字符:剩
2,[0-9]匹配成功。
三个断言均成功,当前位置仍在位置 0。最后 .{6,} 匹配全部 7 个字符,匹配结果为 abc2ABC。
零宽度负向先行断言
(?!...):当前位置之后的文本不能匹配...时,断言成功。
与正向先行断言相反,当 ... 在当前位置匹配失败时,负向断言才算成功。