核心一句话:断言只校验「位置」,不消耗字符,不会把断言里的内容放进匹配结果里。 和
^$\b单词边界是同一类:位置匹配,不抓取字符。
一共4种断言,分成两组:
| 类型 | 语法 | 含义 |
|---|---|---|
| 正向先行(正预测) | (?=exp) | 当前位置后面必须能匹配 exp |
| 正向回顾(正后发) | (?<=exp) | 当前位置前面必须能匹配 exp |
| 负向先行(负预测) | (?!exp) | 当前位置后面不能匹配 exp |
| 负向回顾(负后发) | (?<!exp) | 当前位置前面不能匹配 exp |
1. 正向先行断言 (?=exp)
位置后面要满足 exp,exp 不会被捕获进结果。 例子:
\b[a-z]+(?=ing\b)文本:I'm talking while you're dancing. reading a book
\b[a-z]+:匹配小写单词(?=ing\b):这个单词的结尾位置后面紧跟着 ing+单词边界 匹配结果:talk、danc、read- 注意:匹配出来不带 ing,
ing仅仅用来校验位置条件,不纳入匹配内容。
通俗理解:找「后面是ing」的单词,但是只拿ing前面那部分。
2. 正向回顾断言 (?<=exp)
当前位置前面必须是 exp。exp 在左边,不纳入匹配。
例子:(?<=pre)[a-z]+\b 文本:preschool prehistory prefix test
(?<=pre):匹配位置的前面必须是pre[a-z]+\b:匹配后面单词剩余部分 匹配结果:school、history、fix只拿到 pre 后面的内容,pre只做位置校验,不包含在匹配结果。
3. 负向先行断言 (?!exp)
当前位置后面不能匹配 exp(否定条件)
例子1:\d{3}(?!\d) 含义:匹配3个数字,这3个数字的后面不能是数字 123 在 abc123 可以匹配;123 在 1234 不匹配(后面还有数字4)
例子2:\b((?!abc)\w)+\b 拆解:
(?!abc):这个位置后面不能出现abc((?!abc)\w)+:一个字符,且这个字符开始往后不能是abc,重复多次\b单词边界 匹配:test、ab不匹配:xabcx(里面包含abc连续字符串)作用:匹配不包含连续abc的完整单词
4. 负向回顾断言 (?<!exp)
当前位置前面不能匹配 exp 语法:
(?<!exp)
示例:(?<!pre)[a-z]+\b 含义:匹配单词,单词前面不能是 pre 文本:preschool school 匹配 school(第二个school前面不是pre) preschool里的school不会匹配,因为前面是pre。
区分
- 零宽 = 不占字符 断言只是检查位置条件,不会吃掉文本。
talk(?=ing)匹配talk,文本指针停在k后面,ing还留在原地,不会被消耗。 - 先行 vs 回顾
(?= )/(?! ):向右看(看后面)(?<= )/(?<! ):向左看(看前面)
Previous: 后向引用(反向引用)
Next: 内联注释 (?#comment)