XKCD的API有一些问题,编码也有一些奇怪的问题。
Minor encoding issue with xkcd alt texts in chat
解决方案(在Python中)是将其编码为latin1,然后解码为utf8,但如何在Swift中做到这一点呢?
测试字符串:
"Be careful\u00e2\u0080\u0094it's breeding season"
预期产量:
Be careful—it's breeding season
Python(来自上面的链接):
import json
a = '''"Be careful\u00e2\u0080\u0094it's breeding season"'''
print(json.loads(a).encode('latin1').decode('utf8'))
斯威夫特是怎么做到的?
let strdata = "Be careful\\u00e2\\u0080\\u0094it's breeding season".data(using: .isoLatin1)!
let str = String(data: strdata, encoding: .utf8)
那不管用!
最佳答案
您必须先解码JSON数据,然后提取字符串,最后“修复”字符串。下面是一个自包含的示例,其中的JSON来自https://xkcd.com/1814/info.0.json:
let data = """
{"month": "3", "num": 1814, "link": "", "year": "2017", "news": "",
"safe_title": "Color Pattern", "transcript": "",
"alt": "\\u00e2\\u0099\\u00ab When the spacing is tight / And the difference is slight / That's a moir\\u00c3\\u00a9 \\u00e2\\u0099\\u00ab",
"img": "https://imgs.xkcd.com/comics/color_pattern.png",
"title": "Color Pattern", "day": "22"}
""".data(using: .utf8)!
// Alternatively:
// let url = URL(string: "https://xkcd.com/1814/info.0.json")!
// let data = try! Data(contentsOf: url)
do {
if let dict = (try JSONSerialization.jsonObject(with: data, options: [])) as? [String: Any],
var alt = dict["alt"] as? String {
// Now try fix the "alt" string
if let isoData = alt.data(using: .isoLatin1),
let altFixed = String(data: isoData, encoding: .utf8) {
alt = altFixed
}
print(alt)
// ♫ When the spacing is tight / And the difference is slight / That's a moiré ♫
}
} catch {
print(error)
}
如果你只有一串表格
小心点\u00e2\u0080\u0094是繁殖季节
然后您仍然可以使用
JSONSerialization
解码\uNNNN
转义序列,然后继续如上所述。
一个简单的例子(为简洁起见省略了错误检查):
let strbad = "Be careful\\u00e2\\u0080\\u0094it's breeding season"
let decoded = try! JSONSerialization.jsonObject(with: Data("\"\(strbad)\"".utf8), options: .allowFragments) as! String
let strgood = String(data: decoded.data(using: .isoLatin1)!, encoding: .utf8)!
print(strgood)
// Be careful—it's breeding season