求助:Python正则如何匹配跨多行结构化文本的两种场景
解决多行结构化文本的正则匹配问题
直接上可运行的代码,完美覆盖你提到的两种多行场景:
import re # 测试输入文本 input_text = """11 abc 1 1 22 abc 2 2 def 33 abc def 3 3""" # 正则模式,兼容两种多行场景 pattern = r''' ^(\d+) # 匹配每个条目的开头数字ID \s+ (?: # 场景1:数字对在当前行,后续可能有额外文本行 ([^\n]+?) # 核心文本(非贪婪匹配,直到数字对) \s+(\d+)\s+(\d+) # 捕获末尾的两个数字 (?:\n([^\d].*))? # 可选匹配后续非数字开头的额外文本 | # 场景2:数字对在后续行,前面的多行是核心文本 ((?:.+\n)*?.+?) # 捕获多行核心文本,直到包含数字对的行 \s+(\d+)\s+(\d+) # 捕获末尾的两个数字 ) $ ''' # 执行匹配 matches = re.findall(pattern, input_text, re.MULTILINE | re.DOTALL | re.VERBOSE) # 整理结果为预期格式 final_result = [] for match in matches: if match[1]: # 场景1的结果:ID、核心文本、数字1、数字2、额外文本 final_result.append( (match[0], match[1].strip(), match[2], match[3], match[4].strip() if match[4] else '') ) else: # 场景2的结果:ID、多行核心文本、数字1、数字2、空额外文本 final_result.append( (match[0], match[5].strip(), match[6], match[7], '') ) print(final_result) # 输出:[('11', 'abc', '1', '1', ''), ('22', 'abc', '2', '2', 'def'), ('33', 'abc\ndef', '3', '3', '')]
关键逻辑说明
- 分支结构覆盖场景:用
(?:A|B)分支语法,分别处理「数字对在首行」和「数字对在末行」两种情况 - 精准捕获分组:每个分支对应独立捕获组,最后通过判断分组是否为空来合并成统一格式的结果
- 边界控制避免误匹配:
- 配合
re.MULTILINE让^和$锁定每个条目的首尾 - 额外文本用
[^\d]确保不会误抓下一个以数字开头的新条目 - 非贪婪匹配
+?防止核心文本过度捕获后续内容
- 配合
- 可读性优化:用
re.VERBOSE允许正则添加注释和换行,方便后续维护
内容的提问来源于stack exchange,提问作者Antoine De Groote
相关产品推荐
相关产品推荐

