在Swift中从单个字符串转换为ASCII值的最简单方法是什么?


70

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

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

这太丑了。必须有一个更简单的方法。

Answers:


119

编辑/更新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

14
UnicodeScalar("1")!.value // returns 49

斯威夫特3.1


存在@ixany强制拆包是有原因的,此外,在这种情况下,我们有101%的确定初始化程序不会失败(“ 1”是有效字符)。
Cristik '19

@Cristik不同意。通常,您不能确定输入值不会永远失败。那么为什么不安全地玩呢?更好的办法是:guard let value = UnicodeScalar("1")?.value else { return }
ixany19年

@ixany,您不同意“ 1”是有效字符吗?:)
Cristik

@Cristikif letguard let语句也存在是有原因的。我坚信,只要有可能,您就应该放心。而且,作为经验丰富的开发人员,我们应该在stackoverflow为所有新手提供良好的编码风格和最佳实践。这并不意味着犯罪。
ixany19年

@ixany,是的,同意,我本人尽可能避免强迫拆包,但是在(很少或非常罕见)的情况下,强制拆包是有意义的。在回答问题中,您的“绝不好主意”对我来说似乎有些过激,这就是为什么我回答:)
Cristik

11

现在在Xcode 7.1和Swift 2.1中

var singleChar = "a"

singleChar.unicodeScalars.first?.value

10

您可以使用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

1
@vacawama Swift 4,我遇到错误error: value of type 'String' has no member 'character'。但是当使用“ a”作为NSString时,它的工作是:)
Kamaldeep singh Bhatia

4

斯威夫特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表无关的字节。
Leo Dabus

试试let str = "😀" for ascii in str.utf8 { print(ascii) }// 240,159,152,128`
Leo Dabus

3

您这样做的方式是正确的。如果您不喜欢索引的冗长性,可以通过遍历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

3

一种更短的方法是:

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
}

3

这是我的实现,它返回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兼容。


2

斯威夫特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”
Leo Dabus


1

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

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

注意,这是一个不可靠的初始化器。如果传递的无效字符的值超出ASCII范围0 .. <128,它将崩溃。“致命错误:代码点值不适合ASCII”
Leo Dabus

试试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行
Leo Dabus

0

斯威夫特4

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

要么

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

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


0

迅捷4+

字符到ASCII

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

ASCII到Char

let char = Character(UnicodeScalar(asciiVal)!)

试试let charVal = String("😀").unicodeScalars charVal[charVal.startIndex].value// 128512
Leo Dabus

0

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


#1 使用CharacterasciiValue属性

Character有一个名为的属性asciiValueasciiValue具有以下声明:

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
 */
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.