Устройство кодирует строку ???????? как "\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, но это работает только для символов Unicode, которые могут быть выражены в одной кодовой точке UTF-32.
Вот исходный код, который я использую.
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
Источником закодированной строки является функция org.apache.commons.lang.StringEscapeUtils escapeJava
, которую можно найти здесь.