【问题标题】:Print unicode character from variable (swift)从变量中打印 unicode 字符(swift)
【发布时间】:2015-07-29 09:15:08
【问题描述】:

我遇到了一个我找不到解决方案的问题。 我有一个保存 unicode“1f44d”的字符串变量,我想将其转换为 unicode 字符????。

通常人们会这样做:

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

这就是我的意思:

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

我尝试了其他几种方法,但不知何故,这个魔法背后的工作原理对我来说是隐藏的。

人们应该想象 charAsString 的值来自 API 调用或来自另一个对象。

【问题讨论】:

    标签: xcode swift unicode


    【解决方案1】:

    一种可能的解决方案(解释“内联”):

    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")
    }
    

    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")
    }
    

    另请注意,并非所有代码点都是有效的 Unicode 标量, 比较Validate Unicode code point in Swift


    Swift 3 更新:

    public init?(_ v: UInt32)
    

    现在是 UnicodeScalar 的可失败初始化程序,并检查是否 给定的数字输入是一个有效的 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")
    }
    

    【讨论】:

    • 重用另一个用户的答案来改进你自己的答案在我看来是一种糟糕的做事方式……但我可能错了,也许这很常见。
    • @Fantattitude:信不信由你,但在我使用我自己的之前的答案stackoverflow.com/a/27190430/1187415中的代码编辑此答案之前,我没有看到您的答案。
    • 我相信你不用担心,只是觉得它有点苛刻。经过多年的阅读,我开始参与,所以我可能会犯错误。您仍然可以通过摆脱基数来改进您的答案(默认值在这里似乎可以正常工作)。
    • @Fantattitude:不,它没有,如果我尝试一下,你的代码实际上会崩溃。
    • @MartinR 哦,操场骗了我,我删除后没有更新。
    【解决方案2】:

    这可以分两步完成:

    1. charAsString转换为Int代码
    2. 将代码转换为 unicode 字符

    可以进行第二步,例如像这样

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

    至于第一步,见here如何将十六进制表示的String转换为Int

    【讨论】:

    • 将“1f44d”之类的十六进制字符串转换为 Int 的简短版本:Int(strtoul(charAsString, nil, 16))
    • 这对我很有效;我确实将 vars 转换为 let 并在标量步骤上使用了一个保护以避免它打印一个可选项。
    【解决方案3】:

    从 Swift 2.0 开始,每个 Int 类型都有一个能够将 String 作为输入的初始化程序。然后,您可以轻松地生成一个UnicodeScalar 对应并在之后打印它。无需将字符表示为字符串;)。

    更新:Swift 3.0 更改了 UnicodeScalar 初始化程序

    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)")
    

    【讨论】:

    • 使用 Swift 3.0。除非我还添加感叹号让 uScalar = UnicodeScalar(charAsInt)!,否则您的答案不会打印出所需的结果,否则我看到的是 Optional("\u{0001F44D}")。
    【解决方案4】:

    这里有几种方法:

    let string = "1f44d"
    

    解决方案 1:

    "&#x\(string);".applyingTransform(.toXMLHex, reverse: true)
    

    解决方案 2:

    "U+\(string)".applyingTransform(StringTransform("Hex/Unicode"), reverse: true)
    

    【讨论】:

      【解决方案5】:

      你可以使用

      let char = "-12"
      print(char.unicodeScalars.map {$0.value }))
      

      您将获得如下值:

      [45, 49, 50]
      

      【讨论】:

        【解决方案6】:

        当你尝试使用它时,你不能在 Swift 中使用字符串插值。因此,以下代码将无法编译:

        let charAsString = "1f44d"
        print("\u{\(charAsString)}")
        

        您必须将字符串变量转换为整数(使用init(_:radix:) 初始化程序),然后从该整数创建一个 Unicode 标量。下面的 Swift 5 Playground 示例代码显示了如何继续:

        let validCodeString = "1f44d"
        let validUnicodeScalarValue = Int(validCodeString, radix: 16)!
        let validUnicodeScalar = Unicode.Scalar(validUnicodeScalarValue)!
        print(validUnicodeScalar) // ?
        

        【讨论】:

          【解决方案7】:

          我制作了这个效果很好的扩展:

          extension String {
              var unicode: String? {
                  if let charCode = UInt32(self, radix: 16),
                     let unicode = UnicodeScalar(charCode) {
                      let str = String(unicode)
                      return str
                  }
                  return nil
              }
          }
          

          如何测试:

          if let test = "e9c8".unicode {
              print(test)
          }
          

          //打印:

          【讨论】:

            猜你喜欢
            • 2014-09-16
            • 1970-01-01
            • 2013-05-09
            • 2012-08-14
            • 2016-08-29
            • 2020-08-01
            • 2018-06-22
            相关资源
            最近更新 更多