2015-07-08 8 views
6

Poniższy przykład jest z Strings and Characters documentation:Jak konwersji zastępczego pary do skalarnej unikodowymi Swift

enter image description here

Wartości 55357 (U+D83D w heksanie) i 56374 (U+DC36 w heksanie) są zastępcze pary które tworzą skalar Unicode U+1F436, który jest znakiem DOG FACE. Czy istnieje jakiś sposób, aby iść w przeciwnym kierunku? To znaczy, czy mogę przekonwertować zastępczą parę na skalar?

Próbowałem

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

ale dostałem "Nieprawidłowy skalarne Unicode" błąd.

This Objective C answer i this project wydają się być rozwiązaniami niestandardowymi, ale czy jest coś, co zostało wbudowane w Swift (szczególnie Swift 2.0+), które to robi?

+0

Bezpośrednio podaj punkt kodu: '\ u {1F436}'. Istnieje przykład w dokumencie, który łączysz z 'let sparklingHeart =" \ u {1F496} "//, skalarny kod Unicode U + 1F496' ​​ – nhahtdh

+2

Co zrobić, jeśli nie znam pełnego punktu kodowego? To znaczy, co jeśli znam tylko zastępcze pary? – Suragch

+0

'String' ma' init? (_ Utf16: String.UTF16View) 'metoda, ale nie znalazłem jeszcze jak * utworzyć * a' String.UTF16View' z danej tablicy. - Podobne pytanie (z możliwymi rozwiązaniami) jest tutaj: [Czy istnieje sposób na utworzenie łańcucha z tablicy utf16 w szybkim?] (Http://stackoverflow.com/questions/24542170/is-there-a-way-to -create-a-string-from-utf16-array-in-swift). –

Odpowiedz

1

Biorąc pod uwagę ciąg UTF-16 jednostek kodu (czyli liczb 16-bitowych, jak można uzyskać z String.utf16 czy tylko tablicę liczb), można użyć typu UTF16 i jego decode sposób przekształcić go w UnicodeScalars, które następnie można przekształcić w String.

To trochę grungy element, który pobiera generator (jak to robi przetwarzanie stanowe) i zwraca wyliczenie, które wskazuje wynik (z powiązanym typem skalaru) lub błąd lub zakończenie. Swift 2.0 pasujący wzór sprawia, że ​​o wiele łatwiejsze w użyciu:

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

Zajęło mi trochę czasu, aby nauczyć się niektórych nowych koncepcji (1. [metoda dekodowania] (https://developer.apple.com/library/prerelease/ios/documentation/Swift/Reference/Swift_UTF16_Structure/index.html), 2. generator ([here] (https: // en. wikipedia.org/wiki/Generator_(computer_programming)) i [tutaj] (http://devsmash.com/blog/whats-the-big-deal-with-generators)), 3. [stateful] (http: // programmers.stackexchange.com/a/154499/186547)), ale była to przydatna odpowiedź. Domyślam się, że odpowiedź na moje pierwotne pytanie brzmi: nie, nie ma nic wbudowanego w Swifta, aby zrobić to bezpośrednio, ale nie jest to zbyt trudne do wygenerowania. – Suragch

4

Istnieją wzory do obliczania oryginalny punkt kodu w oparciu o zastępczy pary i vice versa. Od https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae:

Section 3.7 of The Unicode Standard 3.0 definiuje algorytmy do konwersji do i od par zastępczych.

punkt kodowy C większa niż 0xFFFF odpowiada zastępczego pary <H, L> zgodnie z poniższym wzorem:

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

mapowania odwrotnego, czyli z zastępczym pary <H, L> do Unicode punkt kodowy C jest podana przez:

C = (H - 0xD800) * 0x400 + L - 0xDC00 + 0x10000 
Powiązane problemy