Python解析多行文本存字典时无法获取字段完整值的解决方法
问题描述
现有存储每日条目的大型文本文件,内容格式如下:
Date - 01031991 Location- Worcester, MA Status - very long sentence that continues over the next few lines like so. Author- Security 87 Date- 01071991 Location - Fort-Devens, MA Status: another long%$@ sent%$#ence with space and all typ&^%$es of characters. Author - Security 92
当前编写的Python文本转Excel脚本,核心逻辑是逐行按-分割键值对存入字典,代码如下:
myfile = open(txtfile, 'r') dictionary = {} for line in myfile: k, v = line.strip().split("-", maxsplit=1) dictionary[k] = v myfile.close()
脚本运行后无法获取Status字段的完整跨多行内容,仅能读取到Status第一行的文本,实际输出结果为:
print(dictionary) {'Date ': ' 01031991', 'Location': ' Worcester, MA', 'Status ': ' very long sentence that'}
需要调整代码逻辑,将Status等跨多行字段的完整语句正确存入结构中,支撑后续Excel写入。
问题原因
现有脚本默认每一行都是独立的键值对,没有处理三类异常场景:
- 字段分隔符不统一,除了
-还存在:的写法(比如第二个条目的Status:),原有按-分割的逻辑无法兼容 - 值内容跨多行时,后续行没有键名,只有前置缩进空格,现有逻辑会尝试把这类续行也按分隔符拆分,直接导致内容截断
- 条目之间用空行分隔,单个字典结构只能存储一条记录,多条条目需要用列表嵌套字典的结构存储,否则后续条目会覆盖前面的内容
修正方案
调整逐行读取的判断逻辑:读取每一行时先判定当前行是新的字段起始行,还是上一个字段的续行内容:
- 匹配行首是否为合法字段名(Date/Location/Status/Author)+ 分隔符(
-或:),如果匹配成功则新建键值对 - 如果行首是大量缩进空格、没有匹配到字段名规则,就把内容去掉前置冗余空格后,拼接到上一个字段的值后面
- 遇到空行说明当前条目读取结束,把当前条目字典存入结果列表,重置临时字典准备读取下一条
修正后的可运行代码:
import re # 匹配字段行的正则,兼容字段名前后空格、分隔符为-或:的场景 field_pattern = re.compile(r'^\s*(Date|Location|Status|Author)\s*[-:]\s*(.*?)\s*$', re.IGNORECASE) result = [] # 存储所有条目,每个条目对应一个字典,后续写Excel时对应一行 current_entry = {} last_key = None # 记录上一个处理的字段名,用于拼接续行内容 with open(txtfile, 'r', encoding='utf-8') as f: for line in f: line = line.rstrip('\n') # 仅去掉行尾换行符,保留行首空格用于判断是否为续行 # 匹配到空行,说明当前条目结束 if not line.strip(): if current_entry: result.append(current_entry) current_entry = {} last_key = None continue # 尝试匹配是否为新的字段起始行 match = field_pattern.match(line) if match: key = match.group(1).capitalize() # 统一字段名格式,避免大小写、前后空格导致的键名不一致 value = match.group(2) current_entry[key] = value last_key = key else: # 判定为上一个字段的续行,去除前后空格后拼接 if last_key: current_entry[last_key] += ' ' + line.strip() # 处理文件末尾最后一个没有空行收尾的条目 if current_entry: result.append(current_entry) # 验证输出结果 for entry in result: print(entry)
运行后输出如下,Status字段的完整内容已正确拼接,所有字段格式统一:
{'Date': '01031991', 'Location': 'Worcester, MA', 'Status': 'very long sentence that continues over the next few lines like so.', 'Author': 'Security 87'} {'Date': '01071991', 'Location': 'Fort-Devens, MA', 'Status': 'another long%$@ sent%$#ence with space and all typ&^%$es of characters.', 'Author': 'Security 92'}
后续直接遍历result列表写入Excel即可,每个字典对应Excel中的一行数据,键对应列名,值对应单元格内容。
内容的提问来源于stack exchange,提问作者RoiMinuit
相关产品推荐
相关产品推荐

