正则里的 (?=) 和 (?<=) 到底差在哪?
一个是往前看条件、一个是回头确认,方向不同,能不能用还看引擎。
直接答案
括号里以问号开头、不带尖括号的是先行断言,检查当前位置右边的文本;带小于号的是后行断言,检查左边的文本。
把等号换成感叹号就是否定形式,四种写法合起来覆盖右看有、右看无、左看有、左看无。
环视是零宽匹配,不消耗字符,所以可以叠加多个条件;但后行断言在 Python 要求定长,老版本 Safari 直接报语法错误。
看别人的正则,密码校验里一长串带问号和等号的括号,注释写着「至少一位数字」,可它明明没有匹配任何数字。
这类括号叫环视断言,作用是给当前位置加条件,而不是吃掉字符。
1四种写法一次认全
只差一个符号,语义完全相反,认准方向就不会看错。
| 写法 | 含义 | 典型用途 |
|---|---|---|
| (?=…) | 右边必须是这些内容 | 密码里断言后面存在数字 |
| (?!…) | 右边不能是这些内容 | 排除特定后缀 |
| (?<=…) | 左边必须是这些内容 | 取价格数字前面的货币符号之后 |
| (?<!…) | 左边不能是这些内容 | 避免匹配到单词中间 |
记方向的方法:带小于号的是回头看左边,不带的是往右看,感叹号一律表示否定。
2为什么它不吃字符
环视只回答「条件成不成立」,位置不往前移动,所以能连续挂多个条件。
- 零宽的含义
- 匹配成功也不消耗字符
- 密码校验用法
- 逐个断言各类字符是否存在
- 替换时的好处
- 断言内容保留在结果里
- 常见误解
- 以为括号里也要被匹配掉
断言写成必须匹配的样子,是新手最容易出的错:括号里的内容只是条件,不会出现在结果中。
3换语言就可能报错
同一段正则在浏览器里能跑,在 Python 里却抛异常,差别就在后行断言。
- JavaScript
- ES2018 起支持后行断言
- Python
- 后行断言要求定长
- Java
- 支持但量词受限
- 兼容写法
- 先匹配整体再在代码里判断
把正则粘到工具里让它翻成中文说明,比人眼逐字符数括号快,也能顺带看出断言套了几层。
顺着这个问题往下用
全部工具总览 →相关疑问
先行和后行的名字是按什么命名的?
按检查方向命名:先行断言看当前位置之后(右边)的内容,后行断言看之前(左边)的内容,跟书写顺序无关。
(?=) 里面可以写量词吗?
可以,先行断言不限长度,里面写星号加号都行。受限的是后行断言,Python 要求定长,写成变长会报错。
为什么我的断言没有出现在替换结果里?
因为环视是零宽匹配,本身不占字符,被断言的内容不在匹配范围内。想让它出现,就不该用断言而应直接写进捕获组。
多个断言叠在一起会互相干扰吗?
不会,它们在同一个位置各自独立判断,全部成立才算匹配。常用于密码校验里同时要求数字、大小写和特殊符号。
继续看:相关问题与资料
全部问题解答 →
内容标识:本页内容由人工智能辅助生成,并经人工核对与编辑。详见 人工智能生成内容标识说明。
内容说明:本页针对具体使用问题作答,方法步骤与数值由本站自行整理与复算,事实性内容以对应官方规范与文档为准。内容最后核对日期:2026-10-22。若发现错误,欢迎通过页脚反馈入口告知。
内容说明:本页针对具体使用问题作答,方法步骤与数值由本站自行整理与复算,事实性内容以对应官方规范与文档为准。内容最后核对日期:2026-10-22。若发现错误,欢迎通过页脚反馈入口告知。
速查在线工具箱