Python re.split分割文本时如何将分隔符保留至后续结果字符串
问题根因
re.split() 遇到包含捕获组的正则表达式时,会自动将捕获组匹配到的内容作为独立元素插入分割后的列表,所以你当前拿到的返回结果结构是:
- 索引0:第一个分隔符之前的报告头部内容
- 索引1:第一个捕获组匹配到的
Our Ref起始行(第一个实体的开头) - 索引2:第一个起始行之后、第二个起始行之前的内容(第一个实体的剩余部分)
- 索引3:第二个捕获组匹配到的
Our Ref起始行(第二个实体的开头) - 索引4:第二个起始行之后到文本末尾的内容(第二个实体的剩余部分)
这就是为什么分隔符会和后续内容拆分开,没有自动拼接。
推荐实现
方法1:零宽正向预查实现分割(保留头部内容)
用零宽断言匹配实体起始行的位置,这种匹配不会消耗字符,也不会作为独立内容被拆分,正则需要搭配多行模式使用,确保只匹配行首的Our Ref起始标记,避免误判正文内容:
import re # 匹配「后面紧跟符合格式的Our Ref起始行」的位置 sep_pattern = r'(?=^Our Ref :.*?Name:.*?Ref 1 :.*?Ref 2:)' split_res = [seg.strip() for seg in re.split(sep_pattern, pdf_text.strip(), flags=re.M) if seg.strip()]
返回结果说明:
split_res[0]:报告头部元信息(标题、生成日期、总页数、客户代码等公共内容)split_res[1]:第一个完整数据实体(Sky Blue的账户全量记录)split_res[2]:第二个完整数据实体(Green Field的账户全量记录)
方法2:findall直接提取实体(无需头部内容时用)
如果不需要保留开头的公共头部,直接匹配所有从Our Ref起始行开始,到下一个起始行/文本末尾结束的完整实体即可,需要搭配单行模式让.匹配换行符:
entity_pattern = r'^Our Ref :.*?Name:.*?Ref 1 :.*?Ref 2:.*?(?=^Our Ref :|\Z)' entities = [e.strip() for e in re.findall(entity_pattern, pdf_text.strip(), flags=re.M|re.S)]
返回的entities列表直接包含两个拼接完成的独立数据实体,不需要额外处理。
原写法的兼容修正
如果你不想调整原有正则,也可以直接对split返回的结果做步长为2的切片拼接:
split_on_data_entity = re.split(data_entity_sep_pattern, pdf_text.strip()) header = split_on_data_entity[0].strip() entities = [] # 从索引1开始,每两个元素拼接为一个完整实体 for idx in range(1, len(split_on_data_entity), 2): if idx + 1 < len(split_on_data_entity): entities.append( (split_on_data_entity[idx] + split_on_data_entity[idx+1]).strip() )
内容的提问来源于stack exchange,提问作者Himanshu Poddar
相关产品推荐
相关产品推荐

