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

为何Python无法解析含转义引号的合法JSON?

问题:Python JSON模块无法解析验证合法的JSON字符串

以下是测试用的日志字符串:

TEST_LINE = """Oct 21 22:39:28 GMT [TRACE] (Carlos-288) org.some.awesome.LoggerFramework RID=8e9076-4dd9-ec96-8f35-bde193498f: {
    "service": "MyService",
    "operation": "queryShowSize",
    "requestID": "8e9076-4dd9-ec96-8f35-bde193498f",
    "timestamp": 1634815968000,
    "parameters": [
        {
            "__type": "org.some.awsome.code.service#queryShowSizeRequest",
            "externalID": {
                "__type": "org.some.awsome.code.common#CustomerID",
                "value": "48317"
            },
            "CountryID": {
                "__type": "org.some.awsome.code.common#CountryID",
                "value": "125"
            },
            "operationOriginalDate": 1.63462085667E9,
            "operationType": "MeasureWithToes",
            "measureInstrumentIdentifier": "595909-48d2-6115-85e8-b3aa7b"
        }
    ],
    "output": {
        "__type": "org.some.awsome.code.common#queryShowSizeReply",
        "shoeSize": {
            "value": "$ion_1_0 'org.some.awsome.model.processing.ShoeMeasurementBI@1.0'::'org.some.awsome.model.processing.FeetScience@1.0'::{customer_id:\"983017317\",measureInstrumentIdentifierTilda:\"595909-48d2-6115-85e8-b3aa7b\",foot_owner:\"Oedipus\",toe_code:\"LR2X10\",account_number_token:\"1234-2838316-1298470\",token_status:VALID,country_code:GRC,measure_store_format:METRIC}"
        }
    }
}
"""

我用正则提取出其中的JSON部分,验证为合法JSON,但Python的JSON模块解析失败,报错信息如下:

Exception has occurred: JSONDecodeError
Expecting ',' delimiter: line 25 column 156 (char 992)
  File "/Users/decoder/Downloads/json-problem.py", line 44, in read_json
    d = json.loads(line)
        ^^^^^^^^^^^^^^^^
  File "/Users/decoder/Downloads/json-problem.py", line 48, in <module>
    print(read_json(TEST_LINE))
          ^^^^^^^^^^^^^^^^^^^^
json.decoder.JSONDecodeError: Expecting ',' delimiter: line 25 column 156 (char 992)

错误指向output.shoeSize.value中的第一个\",该嵌入的类JSON结构应作为普通字符串处理,且引号已转义,不应提前终止字符串。我的解析代码如下:

import re
import json

FIND_JSON = re.compile(
    r"\w{3} \d{2} (\d{2}[: ]){3}GMT \[[^]]+\] \([^)]+\) "
    r"org.some.awesome.LoggerFramework RID=[^:]+: "
)

def read_json(line: str) -> str | None:
    if not (m := FIND_JSON.match(line)):
        return None
    line = line[m.end(0) :]
    d = json.loads(line)
    return d


print(read_json(TEST_LINE))

尝试过raw_decode()方法,同样失败。

更新1:有评论指出存在未转义的双引号,但我看到的都是冒号后紧跟反斜杠加双引号,且验证合法,怀疑是复制粘贴时的格式转换问题。
更新2:补充了可复现问题的完整代码。


解决方案

问题出在Python字符串的转义处理逻辑上:在Python的三重引号字符串中,\"会被自动解析为单个双引号,而非保留\和"的组合。也就是说,当你定义TEST_LINE时,里面的\"已经被转成了",导致提取后的JSON字符串出现未转义的双引号,触发了解析错误。

举个例子,value字段的内容在Python实际存储时变成了:

$ion_1_0 'org.some.awsome.model.processing.ShoeMeasurementBI@1.0'::'org.some.awsome.model.processing.FeetScience@1.0'::{customer_id:"983017317",...}

这里的"983017317"没有被转义,直接终止了外层字符串,引发报错。

有两种解决方法:

方法1:使用原始字符串定义TEST_LINE

在三重引号前加r,让Python不处理字符串内的转义字符:

TEST_LINE = r"""Oct 21 22:39:28 GMT [TRACE] (Carlos-288) org.some.awesome.LoggerFramework RID=8e9076-4dd9-ec96-8f35-bde193498f: {
    "service": "MyService",
    "operation": "queryShowSize",
    "requestID": "8e9076-4dd9-ec96-8f35-bde193498f",
    "timestamp": 1634815968000,
    "parameters": [
        {
            "__type": "org.some.awsome.code.service#queryShowSizeRequest",
            "externalID": {
                "__type": "org.some.awsome.code.common#CustomerID",
                "value": "48317"
            },
            "CountryID": {
                "__type": "org.some.awsome.code.common#CountryID",
                "value": "125"
            },
            "operationOriginalDate": 1.63462085667E9,
            "operationType": "MeasureWithToes",
            "measureInstrumentIdentifier": "595909-48d2-6115-85e8-b3aa7b"
        }
    ],
    "output": {
        "__type": "org.some.awsome.code.common#queryShowSizeReply",
        "shoeSize": {
            "value": "$ion_1_0 'org.some.awsome.model.processing.ShoeMeasurementBI@1.0'::'org.some.awsome.model.processing.FeetScience@1.0'::{customer_id:\"983017317\",measureInstrumentIdentifierTilda:\"595909-48d2-6115-85e8-b3aa7b\",foot_owner:\"Oedipus\",toe_code:\"LR2X10\",account_number_token:\"1234-2838316-1298470\",token_status:VALID,country_code:GRC,measure_store_format:METRIC}"
        }
    }
}
"""

方法2:对转义符进行二次转义

把字符串中的\"替换为\\",让Python解析后保留\"的组合:

TEST_LINE = """Oct 21 22:39:28 GMT [TRACE] (Carlos-288) org.some.awesome.LoggerFramework RID=8e9076-4dd9-ec96-8f35-bde193498f: {
    "service": "MyService",
    "operation": "queryShowSize",
    "requestID": "8e9076-4dd9-ec96-8f35-bde193498f",
    "timestamp": 1634815968000,
    "parameters": [
        {
            "__type": "org.some.awsome.code.service#queryShowSizeRequest",
            "externalID": {
                "__type": "org.some.awsome.code.common#CustomerID",
                "value": "48317"
            },
            "CountryID": {
                "__type": "org.some.awsome.code.common#CountryID",
                "value": "125"
            },
            "operationOriginalDate": 1.63462085667E9,
            "operationType": "MeasureWithToes",
            "measureInstrumentIdentifier": "595909-48d2-6115-85e8-b3aa7b"
        }
    ],
    "output": {
        "__type": "org.some.awsome.code.common#queryShowSizeReply",
        "shoeSize": {
            "value": "$ion_1_0 'org.some.awsome.model.processing.ShoeMeasurementBI@1.0'::'org.some.awsome.model.processing.FeetScience@1.0'::{customer_id:\\\"983017317\\\",measureInstrumentIdentifierTilda:\\\"595909-48d2-6115-85e8-b3aa7b\\\",foot_owner:\\\"Oedipus\\\",toe_code:\\\"LR2X10\\\",account_number_token:\\\"1234-2838316-1298470\\\",token_status:VALID,country_code:GRC,measure_store_format:METRIC}"
        }
    }
}
"""

两种方法都能让提取后的JSON字符串保留正确的转义引号,从而被Python的json模块正常解析。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 05:57:02