求助:将JavaScript JSON reviver转换为Python实现
JavaScript JSON Reviver 转 Python 实现方案
我在将一段JavaScript的JSON reviver代码转换为Python实现时遇到了问题。
对应的JavaScript代码如下:
const reviver = (_key, value) => { try { return JSON.parse(value, reviver); } catch { if(typeof value === 'string') { const semiValues = value.split(';'); if(semiValues.length > 1) { return stringToObject(JSON.stringify(semiValues)); } const commaValues = value.split(','); if(commaValues.length > 1) { return stringToObject(JSON.stringify(commaValues)); } } const int = Number(value); if(value.length && !isNaN(int)) { return int; } return value; } }; const stringToObject = (str) => { const formatted = str.replace(/"{/g, '{').replace(/}"/g, '}').replace(/"\[/g, '[').replace(/\]"/g, ']').replace(/\\"/g, '"'); return JSON.parse(formatted, reviver); };
该函数的实现目标如下:
- 解析字符串形式的数字
- 按照上述规则解析JSON格式的字符串
- 将类似
"499,504;554,634"的字符串解析为[(499, 504), (554, 634)]
我尝试使用Python的JSONDecoder编写了如下代码,但仍存在问题,恳请提供解决方案。
import json def object_hook(value): try: return json.loads(value) except: if(isinstance(value, str)): semiValues = value.split(';') if(len(semiValues) > 1): return parse_response(json.dumps(semiValues)) commaValues = value.split(',') if(commaValues.length > 1): return parse_response(json.dumps(commaValues)) try: return float(value) except ValueError: return value def parse_response(data: str): formatted = data.replace("\\"{" , "{").replace("}\"", '}').replace("\"[", '[').replace("]\"", ']').replace("\\\"", "\"") return json.load(formatted, object_hook=object_hook)
问题分析与修正方案
你的Python代码存在几个关键问题:
- 语法错误:
commaValues.length是JavaScript写法,Python中应使用len(commaValues);json.load用于读取文件对象,解析字符串需用json.loads。 - 钩子函数误用:
object_hook仅处理解析后的字典对象,无法像JS的reviver那样遍历所有值,需要自定义递归处理逻辑。 - 字符串替换逻辑错误:原JS的正则替换对应Python字符串替换需调整格式,避免转义错误。
- 数字解析不符合需求:直接转float会将整数字符串转为浮点数,需优先尝试转整数。
修正后的完整代码:
import json def reviver(value): # 先尝试递归解析JSON字符串 try: return json.loads(value, object_hook=lambda obj: {k: reviver(v) for k, v in obj.items()}) except (json.JSONDecodeError, TypeError): pass # 处理字符串类型的特殊格式 if isinstance(value, str): # 按分号拆分并递归处理 semi_values = value.split(';') if len(semi_values) > 1: return [reviver(item) for item in semi_values] # 按逗号拆分并递归处理(转为元组匹配需求) comma_values = value.split(',') if len(comma_values) > 1: return tuple(reviver(item) for item in comma_values) # 尝试解析数字:优先整数,再浮点数 try: return int(value) except ValueError: try: return float(value) except ValueError: pass # 所有解析失败则返回原值 return value def parse_response(data: str): # 处理字符串中的多余引号包裹问题,对应JS的stringToObject逻辑 formatted = data.replace('"{', '{').replace('}"', '}')\ .replace('"[', '[').replace(']"', ']')\ .replace('\\"', '"') # 解析后对每个值应用reviver逻辑 parsed = json.loads(formatted) return reviver(parsed) if isinstance(parsed, (dict, list)) else reviver(formatted)
验证示例
测试目标格式的字符串:
test_data = '"499,504;554,634"' result = parse_response(test_data) print(result) # 输出: [(499, 504), (554, 634)]
内容的提问来源于stack exchange,提问作者Albin Médoc
相关产品推荐
相关产品推荐

