2015-07-08 6 views
6

Das folgende Beispiel aus dem Strings and Characters documentation konvertieren genommen wird:Wie Surrogatpaar zu Unicode skalaren in Swift

enter image description here

Die Werte 55357 (U+D83D in hex) und 56374 (U+DC36 in hex) die Platzhalter-Paare sind das bilden den Unicode-Skalar U+1F436, der das Zeichen ist. Gibt es eine Möglichkeit, in die andere Richtung zu gehen? Das heißt, kann ich ein Ersatzpaar in einen Skalar umwandeln?

Ich versuchte

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

aber ich habe einen "Invalid Unicode Skalar" -Fehler.

This Objective C answer und this project scheinen benutzerdefinierte Lösungen zu sein, aber ist irgendetwas in Swift (speziell Swift 2.0+) eingebaut, das das tut?

+0

Geben Sie den Codepunkt direkt an: '\ u {1F436}'. Es gibt ein Beispiel in dem Dokument, das Sie mit 'sinkingHeart =" verbinden \ u {1F496} "//, Unicode-Skalar U + 1F496' ​​ – nhahtdh

+2

Was passiert, wenn ich den vollständigen Codepunkt nicht kenne? Was ist, wenn ich nur die Ersatzpaare kenne? – Suragch

+0

'String' hat eine' init? (_ Utf16: String.UTF16View) 'Methode, aber ich habe noch nicht gefunden, wie man * eine' String.UTF16View' aus einem gegebenen Array * erzeugt. - Eine ähnliche Frage (mit möglichen Lösungen) ist hier: [Gibt es eine Möglichkeit, einen String aus utf16-Array in swift zu erstellen?] (Http://stackoverflow.com/questions/2452170/is-there-a-way-to -create-a-string-from-utf16-array-in-swift). –

Antwort

1

eine Folge von UTF-16-Codeeinheiten (dh 16-Bit-Zahlen, wie sie von String.utf16 oder nur ein Array von Zahlen erhalten) Da man den UTF16 Typ und seine decode Verfahren, um sie in UnicodeScalars verwenden können, die Sie dann in eine String konvertieren können.

Es ist ein bisschen ein grungy Element, das einen Generator nimmt (wie es Stateful-Verarbeitung tut) und gibt eine Aufzählung zurück, die ein Ergebnis (mit einem zugeordneten Typ des Skalars) oder einen Fehler oder Abschluss angibt. Swift 2.0 Pattern-Matching macht es viel einfacher zu bedienen:

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

Es dauerte eine Weile, bis ich einige der neuen Konzepte (1. [Methode decodieren] (https://developer.apple.com/library/prerelease/ios/documentation/Swift/Reference/Swift_UTF16_Structure/index.html), 2. Generator ([hier] (https: // en. wikipedia.org/wiki/Generator_(computer_programming)) und [hier] (http://devsmash.com/blog/whats-the-big-deal-with-generators)), 3. [stateful] (http: // programmers.stackexchange.com/a/154499/186547)), aber das war eine nützliche Antwort. Ich denke, die Antwort auf meine ursprüngliche Frage ist nein, da ist nichts eingebaut, um dies direkt zu tun, aber es ist nicht zu schwer zu generieren. – Suragch

4

Es gibt Formeln, um den ursprünglichen Codepunkt zu berechnen, basierend auf einem Ersatzpaar und umgekehrt. Von https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae:

Section 3.7 of The Unicode Standard 3.0 definiert die Algorithmen für die Konvertierung in und von Ersatzpaaren.

Codepunkt C größer als 0xFFFF auf ein Ersatzpaar <H, L> gemäß der folgenden Formel entspricht:

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

die umgekehrte Zuordnung, dh von einem Ersatzpaar <H, L> in einen Unicode Codepunkt C ist gegeben von:

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