环视
只看不吃:先行断言(lookahead)和后行断言(lookbehind)是零宽断言,检查某个位置前后的内容,然后退回原位,让真正的匹配继续。
阅读规则:指南中的“先行断言与后行断言” →反复操练:正则魔法 →
本课程建立在分组与反向引用之上
你将学到
先行断言 负向先行断言 后行断言 负向后行断言 密码规则
步骤 · 12
- 01只看不吃讲解
- 02正向先行断言狩猎
- 03用先行断言找一个字符狩猎
- 04负向先行断言狩猎
- 05“后面不是”狩猎
- 06正向后行断言狩猎
- 07负向后行断言狩猎
- 08组合断言狩猎
- 09更严格的密码狩猎
- 10不以 s 结尾的单词狩猎
- 11高尔夫:q 后面不是 u狩猎
- 12断言已掌握讲解
正则中的先行断言与后行断言
环视让正则表达式检查某个位置旁边的文本,却不把它算进匹配结果。它们和锚点一样是零宽的:检查要么通过、要么失败,光标都留在原地。正则的其余部分接着从同一个位置继续,就像刚才那一眼从没看过一样。
先行断言向右看。(?=...) 要求后面的文本匹配,(?!...) 要求它不匹配。后行断言向左看:(?<=...) 要求前面的文本匹配,(?<!...) 要求它不匹配。JavaScript 四种都支持,而且它的后行断言可以是任意长度。
当上下文决定是否匹配、却不该出现在匹配结果里时,就用环视:只在后面跟着单位时才匹配数字,只在缺少某个前缀时才匹配单词,或者对同一个输入施加多条规则,比如密码必须含有一个数字和一个大写字母,顺序不限。在狩猎中,环视常常能放过那些和目标字母完全相同的无辜词。
示例
抓住
- 12px
- 300px
- w: 8px
放过
- 12em
- px12
- 12 px
先行断言要求数字后面紧跟
px,但匹配结果本身只有数字。抓住
- #tag
- go #team
- #2026
放过
- tag
- # team
- a#
后行断言检查左边是否有
#,并把它排除在外,所以匹配到的只是标签本身。抓住
- hello
- snake_case
放过
- r2d2
- top10
负向先行断言先用
.*扫描整个单词,所以只要其中任何位置有一个数字,就足以拒绝它。抓住
- play
- display
- player
放过
- replay
- replays
只有当
re紧挨在前面时,负向后行断言才放过play。
常见错误
- 在开头的先行断言里忘了 `. *
。^(?=\d)只检查第一个字符;要表示“任意位置有一个数字”,请写^(?=.*\d)`。 - 以为看过的文本会出现在结果里。 环视从不往匹配里添加字符,所以对
\d+(?=px)做替换时,换掉的是数字,px会保留。 - 把 JavaScript 的后行断言照搬到其他正则引擎。 Python 的
re模块要求(?<=...)里的内容长度固定,许多其他引擎也有类似限制,所以(?<=\$\d*)在 JavaScript 中可用,在那里就会出错。
阅读规则:指南中的“先行断言与后行断言” →反复操练:正则魔法 →