2015-07-29 7 views
9

Mam problem, na który nie mogłem znaleźć rozwiązania. Mam zmienną łańcuchową trzymającą unicode "1f44d" i chcę ją przekonwertować na znak Unicode.Drukuj znak Unicode ze zmiennej (swift)

Zazwyczaj można by zrobić coś takiego:

println("\u{1f44d}") // 

Oto co mam na myśli:

let charAsString = "1f44d" // code in variable 
println("\u{\(charAsString)}") // not working 

Próbowałem kilka innych sposobów, ale jakoś wyrobiska za tym magii pozostają ukryte dla mnie.

Należy sobie wyobrazić wartość charAsString pochodzącą z połączenia API lub z innego obiektu.

Odpowiedz

8

Można to zrobić w dwóch etapach:

  1. przekształcają charAsString do Int kod
  2. kod konwersji do Unicode

Drugi krok można zrobić np jak to

var code = 0x1f44d 
var scalar = UnicodeScalar(code) 
var string = "\(scalar)" 

Jak dla pierwszego etapu, patrz here jak konwertować String w reprezentacji hex do Int

+0

Krótka wersja konwersja ciąg szesnastkowy jak "1f44d" do int: 'Int (strtoul (charAsString Nil, 16))' – yesman82

9

Jednym z możliwych rozwiązań (objaśnienia "inline"):

let charAsString = "1f44d" 

// Convert hex string to numeric value first: 
var charCode : UInt32 = 0 
let scanner = NSScanner(string: charAsString) 
if scanner.scanHexInt(&charCode) { 

    // Create string from Unicode code point: 
    let str = String(UnicodeScalar(charCode)) 
    println(str) // 
} else { 
    println("invalid input") 
} 

Nieco prostsze z Swift 2:

let charAsString = "1f44d" 

// Convert hex string to numeric value first: 
if let charCode = UInt32(charAsString, radix: 16) { 
    // Create string from Unicode code point: 
    let str = String(UnicodeScalar(charCode)) 
    print(str) // 
} else { 
    print("invalid input") 
} 

Należy również zauważyć, że nie wszystkie punkty kodowe są poprawnymi skalarami Unicode, porównaj Validate Unicode code point in Swift.


Aktualizacja Swift 3:

public init?(_ v: UInt32) 

jest teraz failable initializer z UnicodeScalar i sprawdza, czy dana wejściowa numeryczny jest prawidłową wartością skalarną Unicode:

let charAsString = "1f44d" 

// Convert hex string to numeric value first: 
if let charCode = UInt32(charAsString, radix: 16), 
    let unicode = UnicodeScalar(charCode) { 
    // Create string from Unicode code point: 
    let str = String(unicode) 
    print(str) // 
} else { 
    print("invalid input") 
} 
+0

Ponowne użycie kolejną odpowiedź użytkownika, aby poprawić swoją odpowiedź Wydawało mi się, że to okropny sposób na robienie rzeczy tutaj ... Ale mogę się mylić, może to coś zwykłego. – Fantattitude

+1

@Fantitude: Uwierz mi lub nie, ale nie widziałem twojej odpowiedzi zanim zredagowałem tę odpowiedź używając kodu z ** mojej własnej ** poprzedniej odpowiedzi http://stackoverflow.com/a/27190430/1187415. –

+0

Wierzę, że nie martwisz się, po prostu uznałeś, że to trochę trudne. Zaczynam udział po latach czytania, więc mogę popełniać błędy. Nadal możesz poprawić swoją odpowiedź, pozbywając się radix (domyślna wartość wydaje się działać dobrze tutaj). – Fantattitude

3

Począwszy od wersji Swift 2.0, każdy typ Int ma inicjator zdolny do pobrania String jako wejście. Następnie można łatwo wygenerować odpowiadające mu UnicodeScalar i następnie wydrukować. Bez konieczności zmiany reprezentacji znaków jako ciągu;).

ZAKTUALIZOWANE: Swift 3.0 zmieniło UnicodeScalar inicjator

print("\u{1f44d}") // 

let charAsString = "1f44d" // code in variable 

let charAsInt = Int(charAsString, radix: 16)! // As indicated by @MartinR radix is required, default won't do it 
let uScalar = UnicodeScalar(charAsInt)! // In Swift 3.0 this initializer is failible so you'll need either force unwrap or optionnal unwrapping 

print("\(uScalar)") 
+1

Używanie Swift 3.0. Twoja odpowiedź nie drukuje pożądanego wyniku, chyba że dodam również wykrzyknik, aby pozwolić uScalar = UnicodeScalar (charAsInt) !, w przeciwnym razie widzę opcję Opcjonalnie ("\ u {0001F44D}"). – svohara