正则里的 (?=) 和 (?<=) 到底差在哪?

3 个讲解板块 · 关联 1 款站内工具 · 内容最后核对 2026-10-22

一个是往前看条件、一个是回头确认,方向不同,能不能用还看引擎。

直接答案

括号里以问号开头、不带尖括号的是先行断言,检查当前位置右边的文本;带小于号的是后行断言,检查左边的文本。

把等号换成感叹号就是否定形式,四种写法合起来覆盖右看有、右看无、左看有、左看无。

环视是零宽匹配,不消耗字符,所以可以叠加多个条件;但后行断言在 Python 要求定长,老版本 Safari 直接报语法错误。

看别人的正则,密码校验里一长串带问号和等号的括号,注释写着「至少一位数字」,可它明明没有匹配任何数字。

这类括号叫环视断言,作用是给当前位置加条件,而不是吃掉字符。

1四种写法一次认全

只差一个符号,语义完全相反,认准方向就不会看错。

写法含义典型用途
(?=…)右边必须是这些内容密码里断言后面存在数字
(?!…)右边不能是这些内容排除特定后缀
(?<=…)左边必须是这些内容取价格数字前面的货币符号之后
(?<!…)左边不能是这些内容避免匹配到单词中间

记方向的方法:带小于号的是回头看左边,不带的是往右看,感叹号一律表示否定。

2为什么它不吃字符

环视只回答「条件成不成立」,位置不往前移动,所以能连续挂多个条件。

零宽的含义
匹配成功也不消耗字符
密码校验用法
逐个断言各类字符是否存在
替换时的好处
断言内容保留在结果里
常见误解
以为括号里也要被匹配掉

断言写成必须匹配的样子,是新手最容易出的错:括号里的内容只是条件,不会出现在结果中。

3换语言就可能报错

同一段正则在浏览器里能跑,在 Python 里却抛异常,差别就在后行断言。

JavaScript
ES2018 起支持后行断言
Python
后行断言要求定长
Java
支持但量词受限
兼容写法
先匹配整体再在代码里判断

把正则粘到工具里让它翻成中文说明,比人眼逐字符数括号快,也能顺带看出断言套了几层。

相关疑问

先行和后行的名字是按什么命名的?

按检查方向命名:先行断言看当前位置之后(右边)的内容,后行断言看之前(左边)的内容,跟书写顺序无关。

(?=) 里面可以写量词吗?

可以,先行断言不限长度,里面写星号加号都行。受限的是后行断言,Python 要求定长,写成变长会报错。

为什么我的断言没有出现在替换结果里?

因为环视是零宽匹配,本身不占字符,被断言的内容不在匹配范围内。想让它出现,就不该用断言而应直接写进捕获组。

多个断言叠在一起会互相干扰吗?

不会,它们在同一个位置各自独立判断,全部成立才算匹配。常用于密码校验里同时要求数字、大小写和特殊符号。

内容标识:本页内容由人工智能辅助生成,并经人工核对与编辑。详见 人工智能生成内容标识说明。
内容说明:本页针对具体使用问题作答,方法步骤与数值由本站自行整理与复算,事实性内容以对应官方规范与文档为准。内容最后核对日期:2026-10-22。若发现错误,欢迎通过页脚反馈入口告知。