如何用Python将键值对文本转换为带数组结构的JSON格式
如何将带索引键的键值对文本转换为含数组结构的JSON
我需要处理一种无固定格式但采用键值对存储的文本文件,目标是将其转换为JSON格式。目前已经实现了基础的键值对转换,但遇到带有数组索引的键(如Subject[0].MxpCode)时,无法生成对应的JSON数组结构,只能输出扁平的键值对JSON。
输入示例
[DOCUMENT] Headline=This is Headline MainLanguage=EN DocType.MxpCode=1000 Subject[0].MxpCode=BUSNES Subject[1].MxpCode=CONS Subject[2].MxpCode=ECOF Author[0].MxpCode=6VL6 Industry[0].CtbCode=53 Industry[1].CtbCode=5340 Industry[2].CtbCode=534030 Industry[3].CtbCode=53403050 Symbol[0].Name=EXPE.OQ Symbol[1].Name=ABNB.OQ WorldReg[0].CtbCode=G4 Country[0].CtbCode=G26 Country[1].CtbCode=G2V [ENDOFFILE]
现有转换代码
import json with open("file1.csv") as f: lines = f.readlines() data = {} for line in lines: parts = line.split('=') if len(parts) == 2: data[parts[0].strip()] = parts[1].strip() print(json.dumps(data, indent=' '))
当前问题
现有代码会将所有键直接作为顶层属性,输出如下扁平结构(仅示例部分):
{ "Headline": "This is Headline", "Subject[0].MxpCode": "BUSNES", "Subject[1].MxpCode": "CONS" }
无法将Subject[0]、Subject[1]这类带索引的键转换为JSON数组,也无法处理嵌套字段。
期望输出
需要将带索引的键转换为对应数组结构,同时处理嵌套字段,示例如下:
{ "headline": "This is Headline", "mainLanguage": "EN", "docType": { "mxpCode": "1000" }, "subject": [ { "mxpCode": "BUSNES" }, { "mxpCode": "CONS" }, { "mxpCode": "ECOF" } ], "author": [ { "mxpCode": "6VL6" } ], "industry": [ { "ctbCode": "53" }, { "ctbCode": "5340" }, { "ctbCode": "534030" }, { "ctbCode": "53403050" } ], "symbol": [ { "name": "EXPE.OQ" }, { "name": "ABNB.OQ" } ], "worldReg": [ { "ctbCode": "G4" } ], "country": [ { "ctbCode": "G26" }, { "ctbCode": "G2V" } ] }
解决方案
可以通过正则表达式解析键名中的数组标识和嵌套字段,逐步构建包含数组和嵌套对象的JSON结构:
import json import re # 匹配数组类型的键:比如Subject[0].MxpCode array_key_pattern = re.compile(r'^(\w+)\[(\d+)\]\.(\w+)$') # 匹配普通嵌套键:比如DocType.MxpCode nested_key_pattern = re.compile(r'^(\w+)\.(\w+)$') def convert_to_structured_json(file_path): data = {} with open(file_path) as f: for line in f: line = line.strip() # 跳过文件头、尾和空行 if not line or line in ('[DOCUMENT]', '[ENDOFFILE]'): continue key, value = line.split('=', 1) key = key.strip() value = value.strip() # 先尝试匹配数组键 array_match = array_key_pattern.match(key) if array_match: array_name, index, field = array_match.groups() # 转小写(可选,根据需求调整) array_name = array_name.lower() field = field.lower() index = int(index) # 初始化数组 if array_name not in data: data[array_name] = [] # 确保数组长度足够,不足的话补充空对象 while len(data[array_name]) <= index: data[array_name].append({}) # 添加字段到对应索引的对象 data[array_name][index][field] = value continue # 再尝试匹配普通嵌套键 nested_match = nested_key_pattern.match(key) if nested_match: parent_key, field = nested_match.groups() parent_key = parent_key.lower() field = field.lower() # 初始化父对象 if parent_key not in data: data[parent_key] = {} data[parent_key][field] = value continue # 普通顶层键,转小写 data[key.lower()] = value return json.dumps(data, indent=2) # 调用示例 print(convert_to_structured_json("file1.csv"))
代码说明
- 正则匹配:用两个正则分别识别数组类型的键和普通嵌套键,提取关键信息(数组名、索引、字段名/父键、字段名)。
- 数组构建:遇到数组键时,先初始化对应的数组,若索引超出当前数组长度,自动补充空对象,确保索引对应正确的位置。
- 嵌套对象处理:普通嵌套键(如
DocType.MxpCode)会被转换为顶层对象下的嵌套字段。 - 大小写转换:将所有键转换为小写(可根据需求移除该逻辑),让JSON结构更统一。
内容的提问来源于stack exchange,提问作者Atharv Thakur
相关产品推荐
相关产品推荐

