解析含混合引号的JSON遇阻:JSONDecoder与Codable失效求非服务端方案
解决API响应混合引号导致的JSON解析失败问题
针对你遇到的API响应中部分值存在“xxx"这种混合引号的问题,以下是几种无需修改服务端的可行解决方案:
1. 针对性正则替换异常引号对
全局替换弯引号会误伤正常内容,所以可以用正则表达式精准匹配以弯引号开头、直引号结尾的内容块,只替换开头的弯引号为直引号,保留内容内部的弯引号。
以Swift为例,代码示例:
// 将响应数据转为字符串 guard let responseString = String(data: responseData, encoding: .utf8) else { // 处理转码失败情况 throw NetworkError.invalidData } // 正则匹配“开头、"结尾的内容,替换开头的“为" let correctedString = responseString.replacingOccurrences( of: #"“([^"]*)""#, with: #"""$1""""#, options: .regularExpression ) // 转回Data后再用JSONDecoder解析 guard let correctedData = correctedString.data(using: .utf8) else { throw NetworkError.invalidData } let model = try JSONDecoder().decode(MyModel.self, from: correctedData)
正则说明:“([^"]*)" 匹配所有以弯引号开头、直引号结尾的片段,捕获中间的内容(不含直引号),替换为"捕获内容",既修正了异常引号对,又保留了内容内部的弯引号。
2. 自定义Codable初始化逻辑修正字段
如果你明确知道是哪个字段存在引号问题,可以在模型的自定义初始化方法中手动修正该字段的内容:
struct MyModel: Codable { let name: String let description: String // 假设这是有问题的字段 enum CodingKeys: String, CodingKey { case name, description } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) name = try container.decode(String.self, forKey: .name) // 手动提取并修正description字段 let rawDescription = try container.decode(String.self, forKey: .description) if rawDescription.starts(with: "“") && rawDescription.hasSuffix("\"") { // 去掉开头的弯引号和结尾的直引号,直接使用内容 description = String(rawDescription.dropFirst().dropLast()) } else { description = rawDescription } } }
这种方式精准度最高,只会修正目标字段,不会影响其他内容。
3. 借助第三方JSON库预处理
如果API响应结构复杂,多个字段可能存在类似问题,可以用SwiftyJSON这类库先解析为灵活的JSON对象,遍历并修正异常字段后再转成Codable模型:
import SwiftyJSON // 先解析为JSON对象 let json = JSON(data: responseData) // 遍历所有字段检查并修正(或直接定位目标字段) for (key, subJson) in json { if var strValue = subJson.string { if strValue.starts(with: "“") && strValue.hasSuffix("\"") { strValue = "\"" + String(strValue.dropFirst().dropLast()) + "\"" json[key] = JSON(stringLiteral: strValue) } } } // 将修正后的JSON转回Data再解析 guard let correctedData = json.rawData() else { throw NetworkError.invalidData } let model = try JSONDecoder().decode(MyModel.self, from: correctedData)
内容的提问来源于stack exchange,提问作者Josleyn Santos
相关产品推荐
相关产品推荐

