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

使用kotlinx.serialization解析API JSON时嵌套引号问题求助

解决kotlinx.serialization解析含未转义嵌套引号JSON的问题

核心问题是你拿到的是无效JSON——字符串值内部的引号未做转义(比如"key": "some "awesome" value"),kotlinx.serialization作为严格的JSON解析库,必然会抛出JsonDecodingException。下面给出两种可行的解决思路:

方案一:预处理JSON字符串修复未转义引号

直接在解析前修复JSON格式问题,用正则精准定位值部分的未转义引号并转义。以下是Kotlin实现代码:

import kotlin.text.Regex

fun fixMalformedJson(rawJson: String): String {
    // 正则逻辑:匹配键值对中值部分的内容(排除键的引号和结构符号)
    val valuePattern = Regex("(?<=:\\s*\")(.*?)(?=\"(?:,|\\s*}))")
    return valuePattern.replace(rawJson) { match ->
        // 将值内部的未转义引号替换为转义后的\"
        match.value.replace("\"", "\\\\\"")
    }
}

正则生效逻辑说明

  • (?<=:\\s*\"):正向断言,确保当前匹配位置前是: + 可选空格 + 字符串起始引号,避免误匹配键的引号。
  • (.*?):非贪婪匹配值内容,防止过度匹配到其他JSON结构。
  • (?=\"(?:,|\\s*})):正向断言,确保当前匹配位置后是字符串结束引号 + 逗号/大括号,精准锁定值的范围。

使用时先处理原始JSON,再传入解析器:

val rawJson = // 从API获取的原始JSON字符串
val fixedJson = fixMalformedJson(rawJson)
val result = Json.decodeFromString<YourDataClass>(fixedJson)

方案二:自定义宽松解析器(进阶)

如果预处理正则仍有遗漏场景,可以尝试开启kotlinx.serialization的宽松解析模式,但这种方式对未转义引号的支持有限,仅推荐作为备选:

val lenientJson = Json {
    isLenient = true
    ignoreUnknownKeys = true
    // 可选:允许未转义的控制字符(按需开启)
    allowUnquotedControlChars = true
}

你之前正则失效的原因分析

  • 第一个正则/([^:]+:"(.*)"(.*"})/g:匹配逻辑混乱,分组范围错误,无法精准定位值内部的引号。
  • replace("\"\"", "\""):仅处理连续双引号,而你的问题是单个未转义引号,完全不匹配场景。
  • 第三个正则replace("(\"(?:[^\"]|\\\\\")*\")\"", "$1"):仅处理字符串末尾多出来的引号,对字符串中间的未转义引号无效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 19:52:38