我在String中收到格式不正确的unicode

时间:2016-08-11 15:33:34

标签: ios swift xcode

我正在使用一个Web API,它提供了如下字符串:

"Eat pok\u00e9."

Xcode抱怨

  

unicode转义后的大括号中的预期十六进制代码

我的理解是它应该转换为pok\u{00e9},但我不知道如何实现这一点。

有没有人能指出我正确的方向让我开发一种转换方法,因为这个API有很多?

加成: 我还需要从字符串中删除\n

3 个答案:

答案 0 :(得分:1)

您可能希望向我们提供有关原始服务器有效负载外观的更多上下文,并向我们展示您如何显示字符串。在调试器中检查字符串的一些方法(或者如果您正在查看原始JSON)将显示转义字符串,但如果您在应用程序中使用该字符串,则会看到实际的Unicode字符。

我想知道你是否只是在看原始JSON。 例如,我将JSON {"foo": "Eat pok\u00e9."}传递给以下代码:

let jsonString = String(data: data, encoding: NSUTF8StringEncoding)!
print(jsonString)
let dictionary = try! NSJSONSerialization.JSONObjectWithData(data, options: []) as! [String: String]
print(dictionary["foo"]!)

输出:

{"foo": "Eat pok\u00e9."}
Eat poké.

顺便说一下,这个标准的JSON转义语法不应该与Swift的字符串文字转义语法混淆,其中十六进制序列必须用大括号括起来:

print("Eat pok\u{00e9}.")

Swift在其字符串文字中使用不同的转义语法,不应与JSON等格式使用它混淆。

答案 1 :(得分:0)

\u{00e9}是一种特定于Swift String文字的格式。编译代码时,会解析此表示法并将其转换为它所代表的实际Unicode标量。

您收到的是一个以特定方式转义Unicode标量的字符串。将这些转义的Unicode标量转换为它们所代表的Unicode标量,请参阅此answer.

答案 2 :(得分:0)

@Rob为服务器传递无效的Swift字符串文字提供了一个很好的解决方案。

如果您需要将“Eat pok \ u00e9。\ n”转换为Eat poké,可以使用Swift 3 regex进行如下操作。

var input = "Eat pok\\u00e9.\n"

// removes newline
input = String(input.characters.map {
    $0 == "\n" ? " " : $0
})

// regex helper function for sanity's sake
func regexGroup(for regex: String!, in text: String!) -> String {

    do {
        let regex = try RegularExpression(pattern: regex, options: [])
        let nsString = NSString(string: text)
        let results = regex.matches(in: text, options: [], range: NSMakeRange(0, nsString.length))
        let group = nsString.substring(with: results[0].range)
        return group
    } catch let error as NSError {
        print("invalid regex: \(error.localizedDescription)")
        return ""
    }
}

let unicodeHexStr = regexGroup(for:"0\\w*", in: input)
let unicodeHex = Int(unicodeHexStr, radix: 16)!
let char = Character(UnicodeScalar(unicodeHex)!)

let replaced = input.stringByReplacingOccurrencesOfString("\\u"+unicodeHexStr, withString: String(char))

// prints "Eat poké"
print(replaced)