如何将指定格式的文本文件读取为JSON格式?
问题描述
需要将以下格式的文本文件读取并转换为JSON格式:
random_seed: 42 dataset_config { data_sources { abc: "xyz" def: "qwerty" } }
尝试的代码及错误结果:
import json import ast with open(raw_data) as f: data = f.read() data = data.splitlines() def Convert(a): it = iter(a) res_dct = dict(zip(it, it)) return res_dct data = Convert(data) print(data)
输出结果:
{'random_seed: 42': 'dataset_config {', ' data_sources {': ' abc: "xyz"', ' def: "qwerty"': ' }'}
正确转换方法
原代码的问题在于只是简单将相邻行配对成键值对,完全忽略了文本中的嵌套结构,导致结果不符合预期。这种格式是Protocol Buffers文本格式(proto文本),可以通过以下两种方式处理:
方法1:使用Protobuf官方库解析(推荐)
如果能获取到对应的.proto定义文件,这是最准确的解析方式。假设对应的proto定义为:
message Config { int32 random_seed = 1; DatasetConfig dataset_config = 2; } message DatasetConfig { DataSource data_sources = 1; } message DataSource { string abc = 1; string def = 2; }
- 先用
protoc工具将proto文件编译为Python代码:
protoc --python_out=. config.proto
- 编写解析代码并转换为JSON:
import json from google.protobuf.json_format import MessageToJson, MessageToDict import config_pb2 # 编译生成的Python模块 # 解析文本文件 config = config_pb2.Config() with open("your_config.txt", "r") as f: config.ParseText(f.read()) # ParseText专门处理proto文本格式 # 转换为JSON字符串 json_str = MessageToJson(config) print(json_str) # 或者转换为Python字典后再转JSON config_dict = MessageToDict(config) print(json.dumps(config_dict, indent=2))
方法2:手动解析(无proto文件时)
如果没有对应的proto定义,可以手动实现嵌套结构的解析逻辑:
import json def parse_proto_text(text): # 预处理:去除空行和首尾空格 lines = [line.strip() for line in text.splitlines() if line.strip()] stack = [{}] # 用栈处理嵌套结构 current_key = None for line in lines: if line.endswith('{'): # 处理嵌套节点的开始 key = line[:-1].strip() nested_dict = {} stack[-1][key] = nested_dict stack.append(nested_dict) elif line == '}': # 处理嵌套节点的结束 stack.pop() else: # 处理键值对 key, value = line.split(':', 1) key = key.strip() value = value.strip().strip('"') # 尝试转换数值类型 if value.isdigit(): value = int(value) stack[-1][key] = value return stack[0] # 读取并解析文件 with open("your_config.txt", "r") as f: raw_data = f.read() result_dict = parse_proto_text(raw_data) # 转换为JSON json_result = json.dumps(result_dict, indent=2) print(json_result)
两种方法最终都会得到符合预期的JSON结果:
{ "random_seed": 42, "dataset_config": { "data_sources": { "abc": "xyz", "def": "qwerty" } } }
内容的提问来源于stack exchange,提问作者Akshay
相关产品推荐
相关产品推荐

