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

如何处理嵌套JSON并实现占位符查找替换(解决非字符串类型值报错问题)

解决占位符替换时的类型错误问题

这个问题的核心在于你没有区分两种不同的占位符场景,同时原代码的参数存在性判断有逻辑漏洞。下面是修复后的完整代码,以及关键修改点的解释:

修复后的代码

import re

START_DELIMITER = '<'
END_DELIMITER = '>'

def format_params(d, params_lookup):
    if isinstance(d, list):
        return [format_params(item, params_lookup) for item in d]
    if isinstance(d, dict):
        return {key: format_params(value, params_lookup) for key, value in d.items()}
    if isinstance(d, str):
        # 先判断是否是完整的占位符(比如"<year>")
        full_match = re.fullmatch(
            f"{re.escape(START_DELIMITER)}(\\w+){re.escape(END_DELIMITER)}", 
            d
        )
        if full_match:
            param = full_match.group(1)
            if param not in params_lookup:
                raise Exception(f"Parameter {d} is not found in the mapping")
            # 直接返回原类型的值,不转字符串
            return params_lookup[param]
        
        # 再处理字符串中嵌入的占位符(比如"<population> million")
        partial_matches = re.findall(
            f"{re.escape(START_DELIMITER)}(\\w+){re.escape(END_DELIMITER)}", 
            d
        )
        if partial_matches:
            result = d
            for param in partial_matches:
                if param not in params_lookup:
                    raise Exception(f"Parameter {START_DELIMITER}{param}{END_DELIMITER} is not found in the mapping")
                # 把 lookup 值转成字符串后再替换
                result = result.replace(
                    f"{START_DELIMITER}{param}{END_DELIMITER}", 
                    str(params_lookup[param])
                )
            return result
        
        # 没有占位符的字符串直接返回
        return d
    # 非字符串类型直接返回
    return d

# 测试用例
params_lookup = {"population":47, "year":2022, "valid":True, "end":"colls", "num":23, "items":"more"}
record = {"country":"zzzx", "metrics":{"population":"<population> million", "currency":"Euro", "year":"<year>"}, "valid":"<valid>", "others":["<num>", 2, 3], "name":"<items>"}

print(format_params(record, params_lookup))

关键修改点说明

  1. 修复参数存在性判断逻辑
    原代码用if not params_lookup.get(param)会把False、0这类合法的参数值误判为"不存在",改成if param not in params_lookup才能准确判断参数是否在查找字典中。

  2. 区分两种占位符场景

    • 完整占位符:如果字符串本身就是一个完整的占位符(比如<year>),直接返回查找字典中的原类型值(比如整数2022、布尔值True),不需要转成字符串。
    • 嵌入型占位符:如果字符串中包含占位符但不是整个字符串都是(比如<population> million),则把查找值转成字符串后再执行替换,保证replace()方法不会报错。
  3. 使用re.escape处理分隔符
    虽然当前的分隔符<和>不是正则特殊字符,但用re.escape包裹可以避免未来修改分隔符时出现正则语法错误,是更健壮的写法。

运行这段代码后,你会得到完全符合预期的结果:

{
    "country": "zzzx",
    "metrics": {
        "population": "47 million",
        "currency": "Euro",
        "year": 2022
    },
    "valid": True,
    "others": [23, 2, 3],
    "name": "more"
}

内容的提问来源于stack exchange,提问作者kites

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 11:12:32