2015-07-08 2 views
6

Следующий пример взят из Strings and Characters documentation:Как конвертировать суррогатную пару в скаляр Unicode в Swift

enter image description here

Значения 55357 (U+D83D в шестнадцатеричном) и 56374 (U+DC36 в шестнадцатеричном) являются суррогатными парами которые образуют скаляр Unicode U+1F436, который является символом DOG FACE. Есть ли способ пойти в другую сторону? То есть, могу ли я преобразовать суррогатную пару в скаляр?

Я попытался

let myChar: Character = "\u{D83D}\u{DC36}" 

, но я получил ошибку "Invalid Unicode скалярную".

This Objective C answer10 и this project, по-видимому, являются обычными решениями, но есть ли что-либо встроенное в Swift (особенно Swift 2.0+), которое это делает?

+0

Укажите код: '\ И {1F436}'. В документе вы ссылаетесь на 'let sparklingHeart =" \ u {1F496} "//, Unicode-скаляр U + 1F496' ​​ – nhahtdh

+2

Что делать, если я не знаю полной кодовой точки? То есть, если я знаю только суррогатные пары? – Suragch

+0

'String' имеет' init? (_ Utf16: String.UTF16View) 'метод, но я еще не нашел, как * create * a' String.UTF16View' из заданного массива. - Аналогичный вопрос (с возможными решениями) находится здесь: [Есть ли способ создать строку из массива utf16 в swift?] (Http://stackoverflow.com/questions/24542170/is-there-a-way-to -create-а-строковое из-utf16-массив-в-Swift). –

ответ

1

Даны последовательность UTF-16 блоков коды (т.е. 16-разрядные числа, такие, как вы получите от String.utf16 или просто массива чисел), вы можете использовать тип UTF16 и его метод decode, чтобы превратить его в UnicodeScalars, который затем можно преобразовать в String.

Это немного шероховатый элемент, который принимает генератор (как он обрабатывает состояние) и возвращает перечисление, которое указывает результат (со связанным типом скаляра) или ошибку или завершение. Swift соответствие 2,0 модели делает его намного проще в использовании:

let u16data: [UInt16] = [0xD83D,0xDC36] 
//or let u16data = "Hello, ".utf16 

var g = u16data.generate() 
var s: String = "" 
var utf16 = UTF16() 
while case let .Result(scalar) = utf16.decode(&g) { 
    print(scalar, &s) 
} 
print(s) // prints 
+0

Мне потребовалось немного времени, чтобы изучить некоторые новые концепции (1. [метод декодирования] (https://developer.apple.com/library/prerelease/ios/documentation/Swift/Reference/Swift_UTF16_Structure/index.html), 2. generator ([здесь] (https: // ru. wikipedia.org/wiki/Generator_(computer_programming)) и [здесь] (http://devsmash.com/blog/whats-the-big-deal-with-generators)), 3. [stateful] (http: // programers.stackexchange.com/a/154499/186547)), но это был полезный ответ. Я предполагаю, что ответ на мой первоначальный вопрос - нет, в Swift нет ничего, чтобы сделать это напрямую, но его не так сложно создать. – Suragch

4

Есть формулы для расчета исходной точки коды, основанной на суррогатную пару, и наоборот. От https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae:

Section 3.7 of The Unicode Standard 3.0 определяет алгоритмы для преобразования и из суррогатных пар.

Точка кода C больше 0xFFFF соответствует суррогатной паре <H, L> по следующей формуле:

H = Math.floor((C - 0x10000)/0x400) + 0xD800 
L = (C - 0x10000) % 0x400 + 0xDC00 

обратного отображение, т.е. от суррогатной пары <H, L> к Юникоду точки коды C, является предоставленные:

C = (H - 0xD800) * 0x400 + L - 0xDC00 + 0x10000