非JSON兼容的Protobuf风格目标检测结果字符串解析优化咨询
最优解析方案:用Protobuf官方文本解析库
既然你处理的是Protobuf文本格式,官方原生解析工具是最靠谱的选择——完全适配格式规则,比正则或字符串替换稳定得多,也能轻松应对字段嵌套、类型变化等场景。
步骤实现
定义匹配的Protobuf结构文件
根据你的ObjectDetectionPredictionResult结构,编写.proto文件(字段名、类型需和实际数据一致,示例如下):syntax = "proto3"; message ObjectDetectionPredictionResult { string current_time = 1; repeated IdentifiedBox identified_boxes = 2; } message IdentifiedBox { float x_min = 1; float y_min = 2; float x_max = 3; float y_max = 4; string label = 5; float score = 6; }生成Python解析代码
用protoc编译proto文件,生成对应Python类:protoc --python_out=. your_proto_file.proto解析文本并转JSON
借助google.protobuf.text_format解析字符串,再转换为字典后生成目标JSON:from google.protobuf.text_format import Parse from your_proto_file_pb2 import ObjectDetectionPredictionResult import json # 从其他进程接收的Protobuf文本字符串 proto_text = """ current_time: "2024-05-20 14:30:00" identified_boxes { x_min: 100.5 y_min: 80.2 x_max: 200.7 y_max: 180.3 label: "car" score: 0.95 } identified_boxes { x_min: 300.1 y_min: 150.6 x_max: 400.4 y_max: 250.8 label: "person" score: 0.92 } """ # 解析文本到Protobuf对象 result = ObjectDetectionPredictionResult() Parse(proto_text, result) # 把Protobuf对象转成Python字典 def proto_to_dict(proto_obj): result_dict = {} for field in proto_obj.DESCRIPTOR.fields: value = getattr(proto_obj, field.name) if field.type == field.TYPE_MESSAGE: if field.label == field.LABEL_REPEATED: result_dict[field.name] = [proto_to_dict(item) for item in value] else: result_dict[field.name] = proto_to_dict(value) elif field.type == field.TYPE_ENUM: result_dict[field.name] = value.name else: result_dict[field.name] = value return result_dict # 生成最终JSON output_json = json.dumps(proto_to_dict(result), indent=2) print(output_json)
备选方案:手动转换为JSON兼容格式(临时场景用)
如果不想依赖Protobuf编译,可通过字符串替换+字段格式化快速处理,适合临时调试:
import json def proto_text_to_json(proto_text): lines = [line.strip() for line in proto_text.splitlines() if line.strip()] current_time = None boxes = [] current_box = {} in_box = False for line in lines: if line.startswith("current_time:"): # 提取时间并补引号 time_val = line.split(":", 1)[1].strip() current_time = time_val if time_val.startswith('"') else f'"{time_val}"' elif line == "identified_boxes {": in_box = True current_box = {} elif line == "}": in_box = False boxes.append(current_box) elif in_box: # 处理box内字段,补JSON格式的键值对 key, val = line.split(":", 1) key = key.strip() val = val.strip() # 数字直接保留,字符串补引号 if not val.replace(".", "").isdigit(): val = f'"{val}"' current_box[key] = float(val) if "." in val else int(val) if val.isdigit() else val.strip('"') # 组装成目标JSON结构 result = { "current_time": current_time.strip('"'), "identified_boxes": boxes } return json.dumps(result, indent=2) # 测试示例 proto_text = """ current_time: 2024-05-20 14:30:00 identified_boxes { x_min: 100.5 y_min: 80.2 x_max: 200.7 y_max: 180.3 label: car score: 0.95 } identified_boxes { x_min: 300.1 y_min: 150.6 x_max: 400.4 y_max: 250.8 label: person score: 0.92 } """ print(proto_text_to_json(proto_text))
方案对比
- Protobuf官方库:稳定、灵活,支持复杂嵌套结构,字段类型自动处理,适合长期维护的项目,唯一成本是需要定义proto文件并编译。
- 手动字符串转换:无需额外依赖,适合快速调试,但对格式变化兼容性差,新增字段或调整结构时容易出错。
内容的提问来源于stack exchange,提问作者Sebastian
相关产品推荐
相关产品推荐

