设备将字符串“????????”编码为"\uD83E\uDD1B\uD83C\uDFFD"
。该字符串中表示的十六进制数字来自字符的 UTF-16 十六进制编码。 Unicode 代码点U+1F91B, U+1F3FD
从 UTF-32 十六进制编码获取其数字。
就拿后面的这个来说,在 Swift 中我们可以做一个像这样的文字“\u{1F91B}\u{1F3FD}”,我们将得到预期的字符“????????”。
如何从 UTF-16 十六进制字符串转换"\uD83E\uDD1B\uD83C\uDFFD"
得到“????????”?
我尝试获取字符串并将其转换为[UInt32]
32 位整数数组,然后使用它创建 unicode 标量,但这仅适用于可以用单个 UTF-32 代码点表示的 Unicode 字符。
这是我正在使用的源代码。
extension String {
func decodeBlock() -> String {
let strings = self.components(separatedBy: "\\u")
var scalars : [UInt32] = []
var value: UInt32 = 0
for string in strings {
print(string)
let scanner = Scanner(string: string)
if scanner.scanHexInt32(&value) {
scalars.append(value)
}
}
let utf32chars = scalars
var str = ""
var generator = utf32chars.makeIterator()
var utf32 : UTF32 = UTF32()
var done = false
while !done {
let r = utf32.decode(&generator)
switch (r) {
case . emptyInput:
done = true
case .scalarValue(let val):
str.append(Character(val))
case .error:
return "$"
}
}
return str
return self
}
}
它改编自类似问题的答案中的代码。https://stackoverflow.com/a/41412056/731773 https://stackoverflow.com/a/41412056/731773
编码字符串的来源是 org.apache.commons.lang.StringEscapeUtilsescapeJava
可以找到函数here https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/StringEscapeUtils.html#escapeJava(java.lang.String).
这有点作弊,但 UTF-16 恰好是NSString
所以你可以借用以下方法NSString
实现它:
extension String {
func decodeBlock() -> String? {
var chars = [unichar]()
for substr in self.components(separatedBy: "\\u") where !substr.isEmpty {
if let value = UInt16(substr, radix: 16) {
chars.append(value)
} else {
return nil
}
}
return NSString(characters: chars, length: chars.count) as String
}
}
if let decoded = "\\uD83E\\uDD1B\\uD83C\\uDFFD".decodeBlock() {
print(decoded)
} else {
print("Cannot decode")
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)