Python正则匹配可选后续行异常:Case2匹配结果不符合预期
解决STATUS行与对应可选MISC行的正则匹配问题
需求说明
要匹配日志中含STATUS的行,以及可选的对应MISC行(要求STATUS行必须在MISC行之前,且MISC行的val编号需与STATUS行一致)。现有正则在Case1中能正常获取2组结果,但Case2中会跳过第二个STATUS行,仅得到1个匹配,期望Case2也能得到2个匹配(第一个匹配无MISC信息)。
测试示例
Case1(正常匹配场景)
[01:32:12.036,000]
label: val3. STATUS = 0x1
[01:32:12.036,001]label: val3. MISC = 0x8
[02:58:34.971,000]label: val2. STATUS = 0x2
Case2(存在跨STATUS行的MISC场景)
[01:32:12.036,000]
label: val3. STATUS = 0x1
[02:58:34.971,000]label: val2. STATUS = 0x2
[01:32:12.036,001]label: val2. MISC = 0x6
原正则问题分析
原正则:
label: val(\d+). STATUS = (0x[0-9a-fA-F]+)(.*?(label: val(\d+). MISC = (0x[0-9a-fA-F]+)))?"
核心问题:
- 未限制MISC行的
val编号与STATUS行一致,可能匹配到其他编号的MISC .*?会无差别匹配中间内容,包括其他STATUS行,导致第二个STATUS被包含进第一个匹配的范围,最终只输出1个匹配结果
修正后的正则
label: val(\d+)\. STATUS = (0x[0-9a-fA-F]+)(?:\s*(?!label: val\d+\. STATUS).*?label: val\1\. MISC = (0x[0-9a-fA-F]+))?
正则关键逻辑解释
label: val(\d+)\. STATUS = (0x[0-9a-fA-F]+):匹配STATUS行,捕获val编号(分组1)和STATUS值(分组2)(?:...):非捕获组,包裹可选的MISC匹配逻辑,不占用捕获分组\s*:匹配换行、空格等空白字符,兼容日志的行分隔格式(?!label: val\d+\. STATUS):负前瞻断言,确保在查找MISC行的过程中,不会遇到新的STATUS行,彻底避免跳过后续的STATUS匹配label: val\1\. MISC = (0x[0-9a-fA-F]+):匹配与当前STATUS行val编号一致的MISC行,\1引用分组1的编号,保证两者对应,捕获MISC值(分组3)
效果验证
- Case1:第一个STATUS行(val3)匹配到后续的val3 MISC行,第二个STATUS行(val2)无对应MISC,最终得到2组匹配
- Case2:第一个STATUS行(val3)后面是val2的STATUS行,被负前瞻拦截,不会匹配后续的val2 MISC;第二个STATUS行(val2)匹配到后续的val2 MISC,最终得到2组匹配(第一个无MISC信息)
内容的提问来源于stack exchange,提问作者VinayChoudhary99
相关产品推荐
相关产品推荐

