Как выразить строки в Swift, используя шестнадцатеричные значения Unicode (UTF-16)

Я хочу написать строку Unicode, используя шестнадцатеричные значения в Swift. Я прочитал документацию по String и Character, поэтому я знаю, что могу использовать специальные символы Unicode непосредственно в строках, как показано ниже:

var variableString = "Cat‼" // "Cat" + Double Exclamation + cat emoji

Но я хотел бы сделать это с использованием кодовых точек Unicode. Документы (и этот вопрос) показывают это для символов, но не очень ясно, как это сделать для строк.

(Примечание: хотя ответ кажется мне очевидным сейчас, совсем недавно он не был очевиден. Я отвечаю на свой собственный вопрос ниже, чтобы узнать, как это сделать, а также помочь себе понять терминологию Unicode и как работают быстрые символы и строки.)

2 ответа

Решение

Обновлено для Swift 3

символ

Синтаксис Swift для формирования шестнадцатеричной кодовой точки:

\u{n}

где n - шестнадцатеричное число длиной до 8 цифр. Допустимый диапазон для скаляра Unicode: от U+0 до U+D7FF и от U+E000 до U+10FFFF включительно. (Диапазон от U+D800 до U+DFFF предназначен для суррогатных пар, которые сами не являются скалярами, но используются в UTF-16 для кодирования скаляров с более высокими значениями.)

Примеры:

// The following forms are equivalent. They all produce "C". 
let char1: Character = "\u{43}"
let char2: Character = "\u{0043}"
let char3: Character = "\u{00000043}"

// Higher value Unicode scalars are done similarly
let char4: Character = "\u{203C}" // ‼ (DOUBLE EXCLAMATION MARK character)
let char5: Character = "\u{1F431}" //  (cat emoji)

// Characters can be made up of multiple scalars
let char7: Character = "\u{65}\u{301}" // é = "e" + accent mark
let char8: Character = "\u{65}\u{301}\u{20DD}" // é⃝ = "e" + accent mark + circle

Заметки:

строка

Строки состоят из символов. Посмотрите следующие примеры для некоторых способов сформировать их, используя шестнадцатеричные кодовые точки.

Примеры:

var string1 = "\u{0043}\u{0061}\u{0074}\u{203C}\u{1F431}" // Cat‼

// pass an array of characters to a String initializer
let catCharacters: [Character] = ["\u{0043}", "\u{0061}", "\u{0074}", "\u{203C}", "\u{1F431}"] // ["C", "a", "t", "‼", ""]
let string2 = String(catCharacters) // Cat‼

Преобразование шестнадцатеричных значений во время выполнения

Во время выполнения вы можете преобразовать шестнадцатеричный или Int значения в Character или же String сначала преобразовав его в UnicodeScalar,

Примеры:

// hex values
let value0: UInt8  = 0x43     // 97
let value1: UInt16 = 0x203C   // 22823
let value2: UInt32 = 0x1F431  // 127822

// convert hex to UnicodeScalar
let scalar0 = UnicodeScalar(value0)
// make sure that UInt16 and UInt32 form valid Unicode values
guard
    let scalar1 = UnicodeScalar(value1),
    let scalar2 = UnicodeScalar(value2) else {
    return
}

// convert to Character
let character0 = Character(scalar0) // C
let character1 = Character(scalar1) // ‼
let character2 = Character(scalar2) // 

// convert to String
let string0 = String(scalar0) // C
let string1 = String(scalar1) // ‼
let string2 = String(scalar2) // 

// convert hex array to String
let myHexArray = [0x43, 0x61, 0x74, 0x203C, 0x1F431] // an Int array
var myString = ""
for hexValue in myHexArray {
    if let scalar = UnicodeScalar(hexValue) {
        myString.append(Character(scalar))
    }
}
print(myString) // Cat‼

дальнейшее чтение

От вашего хекса "0x1F52D" до настоящего эмодзи

let c = 0x1F602

Следующим шагом будет получение Uint32 от вашего Hex

let intEmoji = UnicodeScalar(c!).value

из этого вы можете сделать что-то вроде

titleLabel.text = String(UnicodeScalar(intEmoji)!)

здесь у вас есть ""

это работает с диапазоном шестнадцатеричной тоже

let emojiRanges = [
            0x1F600...0x1F636,
            0x1F645...0x1F64F,
            0x1F910...0x1F91F,
            0x1F30D...0x1F52D
        ]

        for range in emojiRanges {
            for i in range {
                let c = UnicodeScalar(i)!.value
                data.append(c)
            }
        }

чтобы получить несколько UInt32 из вашего диапазона Hex для примера

Другие вопросы по тегам