使用大引号时将字符串 JSON 转换为 Swift 中的字典

Convert a string JSON to a dictionary in Swift when curly quotes are used

我有一个字符串 JSON,但它有花哨的弯引号,这使得 NSJSON序列化失败。

let str = "{“title”:\"this is a “test” example\"}"

try! JSONSerialization.jsonObject(with: str.data(using: .utf8)!) // Error

title 周围的引号是双引号,显然 JSON 序列化无法处理它而失败。一种天真的方法是用非卷曲引号简单地替换卷曲引号的所有实例。这种方法的问题是它会改变 test 周围的大引号,而这不应该被改变! title 周围的引号可以更改,但 test 周围的引号不应该。

我该怎么做才能解决这个问题?

如果大引号仅用于键,此正则表达式将完成工作:

let str = "{“title”:\"this is a “test” example\"}"

let strFixed = str.replacingOccurrences(
    of: #"“(.[^”]*)”:\"(.[^\"]*)\""#,
    with: "\"\":\"\"",
    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";
}

说明

“(.[^”]*)”:\"(.[^\"]*)\"
------------------------
“(.[^”]*)”                match everything between curly braces,
                          except the closing curling brace character

          :               separator between keys and values

           \"(.[^\"]*)\"  match everything between double quotes,
                          except the double quote character
    \"\":\"\"
    -------------
    \"\"         place the first captured group between double quotes

          :        separator between keys and values

           \"\"  place the second captured group between double quotes

要解决此问题,您与创建该字符串的人交谈,该字符串目前 包含 JSON,并说服他们创建一个字符串 是否包含JSON。

对于JSON,规则是:如果您的解析器无法解析它,那么它就坏了,您不要碰它。

问题不在于JSON序列化无法处理它。问题是JSON序列化绝对绝不能在任何情况下处理它。因为它不是JSON。