Python如何处理json.loads中的无效JSON字符串(AWS Lambda场景)
AWS Lambda Python处理含未转义字符的JSON字段问题
场景说明
我有一个AWS Lambda Python函数,收到的示例数据如下:
{"time_script_executed": "2022-09-20 11:03:31", "nv_official_build": "unknown", "tool_cmd": "c:\\abc\\1.2.3.4\\tool.exe ts /v /tr http://timestamp.entrust.net/TSS/as /td SHA256 \\"sd.dll" 2>&1", }
Lambda中的处理代码如下:
import json import datetime from botocore.exceptions import ClientError def lambda_handler(event, context): event_body = event["body"] input_dict = json.loads("{}".format(event_body)) now = datetime.datetime.now() input_dict["time_2"] = now.strftime('%Y-%m-%dT%H:%M:%S') input_json = json.dumps(input_dict) try: # 后续步骤将发送input_json ... except ClientError as e: print(e) exit(1) response = { "statusCode": 200 } return response
核心需求
- 将可能在特定属性中包含无效JSON字符的输入数据字符串转换为JSON
- 为JSON新增属性
- 将JSON下发至后续环节
问题描述
由于tool_cmd字段存在未转义的JSON字符,导致json.loads解析报错。若先使用json.dumps进行转义,会转义JSON中所有双引号,但我仅希望转义tool_cmd属性。请问在Python中有没有无需使用正则表达式的简洁处理方式?
解决方案
方法1:使用ast.literal_eval替代json.loads
Python的ast模块提供的literal_eval函数可以解析合法的Python字面量,比json.loads容忍度更高,能处理这类存在未完全转义双引号的字符串。修改代码如下:
import ast import json import datetime from botocore.exceptions import ClientError def lambda_handler(event, context): event_body = event["body"] # 用ast.literal_eval替代json.loads,安全解析不规范字面量 input_dict = ast.literal_eval(event_body) now = datetime.datetime.now() input_dict["time_2"] = now.strftime('%Y-%m-%dT%H:%M:%S') input_json = json.dumps(input_dict) try: # 后续步骤将发送input_json ... except ClientError as e: print(e) exit(1) response = { "statusCode": 200 } return response
ast.literal_eval会自动处理tool_cmd字段内的未转义双引号,且不会改变其他字段的原有格式,操作简洁且安全。
方法2:定位字段单独转义后解析
如果必须使用json.loads,可以通过字符串分割定位tool_cmd字段,单独转义其内部的双引号,再进行解析:
import json import datetime from botocore.exceptions import ClientError def lambda_handler(event, context): event_body = event["body"] # 定位tool_cmd字段值的起始和结束位置 field_prefix = '"tool_cmd": "' start_idx = event_body.find(field_prefix) + len(field_prefix) # 查找字段值的结尾(优先找字段后的",,没有则找JSON结尾的}) end_idx = event_body.find('",', start_idx) if end_idx == -1: end_idx = event_body.rfind('}') - 1 # 提取并转义tool_cmd值内的双引号 tool_cmd_raw = event_body[start_idx:end_idx] tool_cmd_escaped = tool_cmd_raw.replace('"', '\\"') # 拼接修复后的JSON字符串 fixed_body = event_body[:start_idx] + tool_cmd_escaped + event_body[end_idx:] # 解析为字典 input_dict = json.loads(fixed_body) now = datetime.datetime.now() input_dict["time_2"] = now.strftime('%Y-%m-%dT%H:%M:%S') input_json = json.dumps(input_dict) try: # 后续步骤将发送input_json ... except ClientError as e: print(e) exit(1) response = { "statusCode": 200 } return response
这种方法仅针对tool_cmd字段处理,不会影响其他字段的转义状态,但依赖输入JSON的格式稳定性,确保tool_cmd字段的结构符合预期。
内容的提问来源于stack exchange,提问作者cucucool
相关产品推荐
相关产品推荐

