2015-07-08 15 views
6

Il seguente esempio è preso dal Strings and Characters documentation:Come convertire coppia di surrogati Unicode scalare Swift

enter image description here

I valori 55357 (U+D83D in esadecimale) e 56374 (U+DC36 in esadecimale) sono le coppie di surrogati che formano lo scalare Unicode U+1F436, che è il carattere DOG FACE. C'è un modo per andare nella direzione opposta? Cioè, posso convertire una coppia surrogata in uno scalare?

ho cercato

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

ma ho ottenuto un errore "non valido Unicode scalare".

This Objective C answer e this project sembrano soluzioni personalizzate, ma c'è qualcosa incorporato in Swift (specialmente Swift 2.0+) che lo fa?

+0

Specificare direttamente il punto di codice: '\ U {} 1F436'. C'è un esempio nel documento che si collega a 'let sparklingHeart =" \ u {1F496} "//, scalare Unicode U + 1F496' ​​ – nhahtdh

+2

Cosa succede se non conosco il punto di codice completo? Cioè, cosa succede se conosco solo le coppie surrogate? – Suragch

+0

'String' ha un metodo' init? (_ Utf16: String.UTF16View) ', ma non ho ancora trovato come * creare * un' String.UTF16View' da un dato array. - Una domanda simile (con possibili soluzioni) è qui: [C'è un modo per creare una stringa dall'array utf16 in swift?] (Http://stackoverflow.com/questions/24542170/is-there-a-way-to -create-a-stringa-da-utf16-array-in-veloce). –

risposta

1

Dato una sequenza di UTF-16 unità di codice (cioè numeri a 16 bit, come si ottiene da String.utf16 o solo una matrice di numeri), è possibile utilizzare il tipo UTF16 e il suo metodo decode per trasformarlo in UnicodeScalars, che è possibile convertire in un String.

È un elemento un po 'sgangherato, che accetta un generatore (poiché esegue l'elaborazione di stato) e restituisce un enum che indica un risultato (con un tipo di scalare associato) o un errore o un completamento. Swift corrispondenza 2.0 modello rende molto più facile da usare:

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

Mi ci è voluto un po 'per imparare alcuni dei nuovi concetti (1. [metodo di decodifica] (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)) e [qui] (http://devsmash.com/blog/whats-the-big-deal-with-generators)), 3. [stateful] (http: // programmers.stackexchange.com/a/154499/186547), ma questa era una risposta utile. Immagino che la risposta alla mia domanda iniziale sia no, non c'è nulla di integrato in Swift per farlo direttamente, ma non è troppo difficile da generare. – Suragch

4

Non ci sono formule per calcolare il punto di codice originale basata su una coppia di surrogati e viceversa. Da https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae:

Section 3.7 of The Unicode Standard 3.0 definisce gli algoritmi per la conversione da e coppie di surrogati.

Un punto codice C superiore 0xFFFF corrisponde ad una coppia di surrogati <H, L> secondo la seguente formula:

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

La mappatura inversa, cioè da una coppia di surrogati <H, L> ad un Unicode punto C codice, è data da:

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