You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:将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代码存在几个关键问题:

  1. 语法错误:commaValues.length是JavaScript写法,Python中应使用len(commaValues);json.load用于读取文件对象,解析字符串需用json.loads。
  2. 钩子函数误用:object_hook仅处理解析后的字典对象,无法像JS的reviver那样遍历所有值,需要自定义递归处理逻辑。
  3. 字符串替换逻辑错误:原JS的正则替换对应Python字符串替换需调整格式,避免转义错误。
  4. 数字解析不符合需求:直接转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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 16:31:19