零宽断言 & 负向零宽断言

核心一句话:断言只校验「位置」,不消耗字符,不会把断言里的内容放进匹配结果里。^ $ \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+单词边界 匹配结果:talkdancread
  • 注意:匹配出来不带 inging 仅仅用来校验位置条件,不纳入匹配内容。

通俗理解:找「后面是ing」的单词,但是只拿ing前面那部分。

2. 正向回顾断言 (?<=exp)

当前位置前面必须是 exp。exp 在左边,不纳入匹配。

例子:(?<=pre)[a-z]+\b 文本:preschool prehistory prefix test

  • (?<=pre):匹配位置的前面必须是 pre
  • [a-z]+\b:匹配后面单词剩余部分 匹配结果:schoolhistoryfix只拿到 pre 后面的内容,pre 只做位置校验,不包含在匹配结果。

3. 负向先行断言 (?!exp)

当前位置后面不能匹配 exp(否定条件)

例子1:\d{3}(?!\d) 含义:匹配3个数字,这3个数字的后面不能是数字 123abc123 可以匹配;1231234 不匹配(后面还有数字4)

例子2:\b((?!abc)\w)+\b 拆解:

  • (?!abc):这个位置后面不能出现 abc
  • ((?!abc)\w)+:一个字符,且这个字符开始往后不能是abc,重复多次
  • \b 单词边界 匹配:testab 不匹配:xabcx(里面包含abc连续字符串)作用:匹配不包含连续abc的完整单词

4. 负向回顾断言 (?<!exp)

当前位置前面不能匹配 exp 语法:(?<!exp)

示例:(?<!pre)[a-z]+\b 含义:匹配单词,单词前面不能是 pre 文本:preschool school 匹配 school(第二个school前面不是pre) preschool里的school不会匹配,因为前面是pre。


区分

  1. 零宽 = 不占字符 断言只是检查位置条件,不会吃掉文本talk(?=ing) 匹配 talk,文本指针停在k后面,ing还留在原地,不会被消耗。
  2. 先行 vs 回顾
  • (?= ) / (?! )向右看(看后面)
  • (?<= ) / (?<! )向左看(看前面)

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注