【问题标题】:What's the simplest way to convert from a single character String to an ASCII value in Swift?在 Swift 中从单个字符串转换为 ASCII 值的最简单方法是什么?
【发布时间】:2015-07-02 08:02:22
【问题描述】:

我只想在 Swift 中获取单个字符字符串的 ASCII 值。这就是我目前的做法:

var singleChar = "a"
println(singleChar.unicodeScalars[singleChar.unicodeScalars.startIndex].value) //prints: 97

这太丑了。一定有更简单的方法。

【问题讨论】:

    标签: swift string character ascii


    【解决方案1】:

    编辑/更新 Swift 5.2 或更高版本

    extension StringProtocol {
        var asciiValues: [UInt8] { compactMap(\.asciiValue) }
    }
    

    "abc".asciiValues  // [97, 98, 99]
    

    在 Swift 5 中,您可以使用新的字符属性 isASCIIasciiValue

    Character("a").isASCII       // true
    Character("a").asciiValue    // 97
    
    Character("á").isASCII       // false
    Character("á").asciiValue    // nil
    

    旧答案

    你可以创建一个扩展:

    Swift 4.2 或更高版本

    extension Character {
        var isAscii: Bool {
            return unicodeScalars.allSatisfy { $0.isASCII }
        }
        var ascii: UInt32? {
            return isAscii ? unicodeScalars.first?.value : nil
        }
    }
    

    extension StringProtocol {
        var asciiValues: [UInt32] {
            return compactMap { $0.ascii }
        }
    }
    

    Character("a").isAscii  // true
    Character("a").ascii    // 97
    
    Character("á").isAscii  // false
    Character("á").ascii    // nil
    
    "abc".asciiValues            // [97, 98, 99]
    "abc".asciiValues[0]         // 97
    "abc".asciiValues[1]         // 98
    "abc".asciiValues[2]         // 99
    

    【讨论】:

      【解决方案2】:
      UnicodeScalar("1")!.value // returns 49
      

      斯威夫特 3.1

      【讨论】:

      • @ixany 强制展开是有原因的,而且在这种情况下,我们 101% 确定初始化程序不会失败(“1”是有效字符)。
      • @Cristik 不同意。通常,您不能确定输入值不会永远失败。那么为什么不安全地玩呢?更好的方法是:guard let value = UnicodeScalar("1")?.value else { return }.
      • @ixany,您不同意“1”是有效字符吗? :)
      • @Cristik if letguard let 语句的存在也是有原因的。我坚信,只要有可能,您就应该安全行事。作为更有经验的开发人员,我们应该为 stackoverflow 的所有新手提供良好的编码风格和最佳实践。这并不意味着犯罪。
      • @ixany,是的,同意,我自己尽可能避免强制解包,但是有(罕见或非常罕见)强制解包有意义的情况。在答案上下文中,您的“从来都不是一个好主意”对我来说似乎有点过激,这就是我回答的原因:)
      【解决方案3】:

      现在在 Xcode 7.1 和 Swift 2.1 中

      var singleChar = "a"
      
      singleChar.unicodeScalars.first?.value
      

      【讨论】:

        【解决方案4】:

        您可以使用 NSString 的 characterAtIndex 来完成此操作...

        var singleCharString = "a" as NSString
        var singleCharValue = singleCharString.characterAtIndex(0)
        println("The value of \(singleCharString) is \(singleCharValue)")  // The value of a is 97
        

        【讨论】:

        • @vacawama Swift 4,我收到错误 error: value of type 'String' has no member 'character'。但是当使用“a”作为 NSString 时它的工作:)
        【解决方案5】:

        斯威夫特 4.2

        从 Swift 字符串中获取 ASCII 值的最简单方法如下

        let str = "Swift string"
        for ascii in str.utf8 {
            print(ascii)
        }
        

        输出:

        83
        119
        105
        102
        116
        32
        115
        116
        114
        105
        110
        103
        

        【讨论】:

        • 这不是 ascii 值。这将返回一个字节数组。 ascii 以外的字符将返回多个字节,与 ascii 表无关。
        • 试试let str = "?" for ascii in str.utf8 { print(ascii) } // 240, 159, 152, 128`
        【解决方案6】:

        你的做法是对的。如果您不喜欢索引的冗长,可以通过循环遍历 unicode 标量来避免它:

        var x : UInt32 = 0
        let char = "a"
        for sc in char.unicodeScalars {x = sc.value; break}
        

        当然,在这种情况下,您实际上可以省略 break,因为只有一个 unicode 标量。

        或者,转换为 Array 并使用 Int 索引(绝望的最后手段):

        let char = "a"
        let x = Array(char.unicodeScalars)[0].value
        

        【讨论】:

          【解决方案7】:

          执行此操作的更短的方法可能是:

          first(singleChar.unicodeScalars)!.value
          

          与下标版本一样,如果您的字符串实际上是空的,这将崩溃,所以如果您不是 100% 确定,请使用可选:

          if let ascii = first(singleChar.unicodeScalars)?.value {
          
          }
          

          或者,如果你想变得更加偏执,

          if let char = first(singleChar.unicodeScalars) where char.isASCII() {
              let ascii = char.value
          }
          

          【讨论】:

            【解决方案8】:

            这是我的实现,它返回一个 ASCII 值数组。

            extension String {
            
                func asciiValueOfString() -> [UInt32] {
            
                  var retVal = [UInt32]()
                  for val in self.unicodeScalars where val.isASCII() {
                      retVal.append(UInt32(val))
                  }
                  return retVal
                }
            }
            

            注意:是的,它与 Swift 2 兼容。

            【讨论】:

              【解决方案9】:

              斯威夫特 4.1

              https://oleb.net/blog/2017/11/swift-4-strings/

              let flags = "99_problems"
              flags.unicodeScalars.map {
                  "\(String($0.value, radix: 16, uppercase: true))"
              }
              

              结果:

              ["39", "39", "5F", "70", "72", "6F", "62", "6C", "65", "6D", "73"]

              【讨论】:

              • 试试let flags = "?" flags.unicodeScalars.map { "\(String($0.value, radix: 16, uppercase: true))" } // "1F600"
              【解决方案10】:

              斯威夫特 4+

              字符转ASCII

              let charVal = String(ch).unicodeScalars
              var asciiVal = charVal[charVal.startIndex].value
              

              ASCII 转字符

              let char = Character(UnicodeScalar(asciiVal)!)
              

              【讨论】:

              • 试试let charVal = String("?").unicodeScalars charVal[charVal.startIndex].value // 128512
              【解决方案11】:
              var singchar = "a" as NSString
              
              print(singchar.character(at: 0))
              

              斯威夫特 3.1

              【讨论】:

                【解决方案12】:

                UInt8 上还有 UInt8(ascii: Unicode.Scalar) 初始化器。

                var singleChar = "a"
                UInt8(ascii: singleChar.unicodeScalars[singleChar.startIndex])
                

                【讨论】:

                • 请注意,这是一个不会出错的初始化程序。如果您传递其值超出 ascii 范围 0..“致命错误:代码点值不适合 ASCII”
                • try var singleChar = "?" UInt8(ascii: singleChar.unicodeScalars[singleChar.startIndex]) // 致命错误:代码点值不适合 ASCII:文件 /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang -1200.2.10.322/swift/stdlib/public/core/UnicodeScalar.swift,第 354 行`
                【解决方案13】:

                使用 Swift 5,您可以选择以下方法之一来获取字符的 ASCII 数字表示。


                #1。使用CharacterasciiValue 属性

                Character 有一个名为asciiValue 的属性。 asciiValue 有以下声明:

                var asciiValue: UInt8? { get }
                

                此字符的 ASCII 编码值,如果是 ASCII 字符。

                以下 Playground 示例代码展示了如何使用 asciiValue 来获取 字符的ASCII编码值:

                let character: Character = "a"
                print(character.asciiValue) //prints: Optional(97)
                
                let string = "a"
                print(string.first?.asciiValue) //prints: Optional(97)
                
                let character: Character = "?"
                print(character.asciiValue) //prints: nil
                

                #2。使用CharacterisASCII 属性和Unicode.Scalarvalue 属性

                作为替代方法,您可以检查字符串的第一个字符是否为 ASCII 字符(使用 CharacterisASCII 属性)然后获取其第一个 Unicode 标量的数字表示(使用 Unicode.Scalarvalue 财产)。下面的 Playground 示例代码显示了如何继续:

                let character: Character = "a"
                if character.isASCII, let scalar = character.unicodeScalars.first {
                    print(scalar.value)
                } else {
                    print("Not an ASCII character")
                }
                /*
                 prints: 97
                 */
                
                let string = "a"
                if let character = string.first, character.isASCII, let scalar = character.unicodeScalars.first {
                    print(scalar.value)
                } else {
                    print("Not an ASCII character")
                }
                /*
                 prints: 97
                 */
                
                let character: Character = "?"
                if character.isASCII, let scalar = character.unicodeScalars.first {
                    print(scalar.value)
                } else {
                    print("Not an ASCII character")
                }
                /*
                 prints: Not an ASCII character
                 */
                

                【讨论】:

                  【解决方案14】:

                  斯威夫特 4

                  print("c".utf8["c".utf8.startIndex])
                  

                  let cu = "c".utf8
                  print(cu[cu.startIndex])
                  

                  两者都打印 99。适用于任何 ASCII 字符。

                  【讨论】:

                    猜你喜欢
                    • 2012-01-07
                    • 1970-01-01
                    • 1970-01-01
                    • 2011-04-04
                    • 2011-06-23
                    • 2021-07-21
                    • 2012-08-01
                    • 1970-01-01
                    • 2015-12-15
                    相关资源
                    最近更新 更多