使用大引号时,将字符串 JSON 转换为 Swift 中的字典
Posted
技术标签:
【中文标题】使用大引号时,将字符串 JSON 转换为 Swift 中的字典【英文标题】:Convert a string JSON to a dictionary in Swift when curly quotes are used 【发布时间】:2020-01-24 19:18:31 【问题描述】:我有一个字符串 JSON,但它有花哨的大引号导致 NSJSONSerialization 失败。
let str = "“title”:\"this is a “test” example\""
try! JSONSerialization.jsonObject(with: str.data(using: .utf8)!) // Error
title
周围的引号是双引号,显然 JSONSerialization 无法处理它并失败。一种天真的方法是简单地用非卷引号替换所有卷引号实例。这种方法的问题在于它会改变 test
周围的花括号,而这不应该被改变! title
周围的引号可以更改,但test
周围的引号不应该。
我可以做些什么来解决这个问题?
【问题讨论】:
将"
更改为
,"
更改为
和\"
更改为"
?
【参考方案1】:
要解决此问题,您与创建该字符串的人交谈,该字符串目前 不 包含 JSON,并说服他们创建一个 确实 包含 JSON 的字符串。
对于 JSON,规则是:如果您的解析器无法解析它,那么它就坏了,您不要碰它。
问题不在于 JSONSerialization 无法处理它。问题是 JSONSerialization 在任何情况下都绝对不得处理它。因为它不是 JSON。
【讨论】:
【参考方案2】:如果大引号仅用于键,则此正则表达式将完成这项工作:
let str = "“title”:\"this is a “test” example\""
let strFixed = str.replacingOccurrences(
of: #"“(.[^”]*)”:\"(.[^\"]*)\""#,
with: "\"$1\":\"$2\"",
options: .regularExpression
)
// It's strongly recommended to use try/catch instead of force unwrapping.
let json = try! JSONSerialization.jsonObject(with: strFixed.data(using: .utf8)!)
如果我们打印json
,我们会得到正确的结果:
title = "this is a \U201ctest\U201d example";
说明
“(.[^”]*)”:\"(.[^\"]*)\" ---------------------- “(.[^”]*)” 匹配大括号之间的所有内容, 除了右花括号字符 : 键和值之间的分隔符 \"(.[^\"]*)\" 匹配双引号之间的所有内容, 除了双引号字符 \"$1\":\"$2\" ------------- \"$1\" 将第一个捕获的组放在双引号之间 : 键和值之间的分隔符 \"$2\" 将第二个捕获的组放在双引号之间【讨论】:
以上是关于使用大引号时,将字符串 JSON 转换为 Swift 中的字典的主要内容,如果未能解决你的问题,请参考以下文章
AFNetworking 在格式化 JSON 时将我的双打转换为带引号的字符串
当字符串在双引号内有单引号时,如何在Javascript中将此字符串转换为JSON对象