回头看左边
后行断言检查当前位置左侧的内容是否满足条件,位置同样不前进、内容同样不出现在结果里。它的典型用途是「取出某个符号之后的部分」而把符号本身留在匹配结果之外,替换时就不需要再补回符号。
固定宽度是主要限制
多数实现要求后行断言内部的长度固定,因为引擎需要知道该往回看多少字符。对长度不固定的内容,只有部分引擎支持,支持程度与上限各不相同,这是跨语言复用模式时最常遇到的障碍。
基本信息
| 写法 | 圆括号内以问号小于等于开头为正向后行,问号小于感叹号为负向后行 |
|---|---|
| 宽度 | 零宽,不消耗字符 |
| 方向 | 只检查左侧内容 |
| 宽度限制 | 多数实现要求固定宽度,变长支持随引擎与版本而异 |
| 引擎支持 | PCRE、Java、.NET、JavaScript 支持;无回溯引擎通常不支持 |
| 组合使用 | 常与捕获分组或后续内容一起使用,用于定位取值位置 |
典型使用场景
- 提取符号之后的内容,同时把符号排除在结果之外
- 替换时只改数值而保留其前的单位或前缀
- 提取紧跟某个固定前缀之后的编码
- 排除带特定前缀的行,例如已经处理过的记录
- 在日志里截取时间戳之后的正文部分
后行断言的用法
后行断言的用法
(?<=@)[a-z.]+ 取 @ 之后的域名部分,@ 不在结果里
(?<=key=)\w+ 取等号之后的键值
(?<=\$)\d+ 取美元符号之后的金额数字
(?<!\d)\.\d+ 小数点前不能是数字,避免匹配版本号中的点
(?<=,)(?=[^,]+,) 逗号之后且下一个逗号之前的位置
# 固定宽度写法最安全:内容不含不定长量词后行断言写法与限制
| 写法 | 含义 | 常见限制 |
|---|---|---|
| 问号小于等于开头 | 左侧必须满足条件 | 多数实现要求固定宽度 |
| 问号小于感叹号开头 | 左侧必须不满足条件 | 同上 |
| 内部含不定长量词 | 左侧长度可变 | 支持情况随引擎与版本而异 |
| 内部含分组与分支 | 结构更复杂 | 各分支宽度需符合引擎要求 |
方向写反是常见错误:把后行断言写成先行断言,检查就变成了右侧内容,模式会静默地匹配到别的位置。写完后用一个明显不满足左侧条件的样本反测一次。
不需要固定宽度时,可以考虑用捕获分组代替后行断言:把前缀放进分组,读取时忽略第 1 组即可,兼容性更好。