【问题标题】:How to express Strings in Swift using Unicode hexadecimal values (UTF-16)如何使用 Unicode 十六进制值 (UTF-16) 在 Swift 中表达字符串
【发布时间】:2015-09-25 21:12:32
【问题描述】:

我想在 Swift 中使用十六进制值编写一个 Unicode 字符串。我已经阅读了 documentation 的字符串和字符,所以我知道我可以直接在字符串中使用特殊的 Unicode 字符,如下所示:

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

但我想使用 Unicode 代码点来实现。文档(和this question)为字符显示了它,但对于如何为字符串执行它并不是很清楚。

(注意:虽然现在答案对我来说似乎很明显,但不久前还完全不明显。我在下面回答我自己的问题,作为学习如何做到这一点并帮助自己理解的一种方式Unicode 术语以及 Swift 字符和字符串的工作原理。)

【问题讨论】:

    标签: ios string swift unicode character


    【解决方案1】:

    为 Swift 3 更新

    字符

    形成十六进制 code point 的 Swift 语法是

    \u{n}
    

    其中 n 是一个最多 8 位的十六进制数。 Unicode scalar 的有效范围是 U+0 到 U+D7FF 和 U+E000 到 U+10FFFF(含)。 (U+D800 到 U+DFFF 的范围是 surrogate pairs,它们本身不是标量,但在 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 值转换为CharacterString,方法是先将其转换为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‼?
    

    进一步阅读

    【讨论】:

    • @Suragch 我有一个 unicode 字符 \u{0D85}。如何从中获取 Int 值?
    • @Isuru,我在这里重新提出并回答了您的问题:How to convert Unicode Character to Int in Swift
    • @Suragch 非常感谢您的详细回答。我实际上在answer 中找到了如何做到这一点。但是,有一个详尽的解释还是不错的。
    • @Isuru,请注意,在您链接到的答案中,如果 Character 由多个标量组成,则只会返回第一个标量值。任何其他将被忽略。 (例如:let myChar: Character = "\u{65}\u{301}" // é
    • 如何将最多 8 位的十六进制数与 \u{xxxx} 组合?十六进制数是动态的
    【解决方案2】:

    从您的十六进制“0x1F52D”到实际的表情符号

    let c = 0x1F602
    

    下一步可能会从您的 Hex 中获取 Uint32

    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

    【讨论】:

    • 请不要对多个问题发布相同的答案。如果相同的信息确实回答了两个问题,那么一个问题(通常是较新的问题)应该作为另一个问题的副本关闭。您可以通过voting to close it as a duplicate 表明这一点,或者,如果您对此没有足够的声誉,则可以通过raise a flag 表明它是重复的。否则,请务必针对this问题定制答案,不要将相同的答案粘贴到多个位置。
    • 制作了这篇解释其工作原理的 Medium 文章 medium.com/@kamiFR/…
    猜你喜欢
    • 2020-01-18
    • 1970-01-01
    • 2010-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-27
    • 1970-01-01
    相关资源
    最近更新 更多