使用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
相关产品推荐
相关产品推荐

