如何在Swift中判断一个字符是字母数字还是数字

39

我想要统计以下字符串中字母、数字和特殊字符的数量:

let phrase = "The final score was 32-31!"

我尝试了:

for tempChar in phrase {
    if (tempChar >= "a" && tempChar <= "z") {
       letterCounter++
    }
// etc.

但我一直出错。我尝试了各种各样的变化-仍然出错-例如:

找不到接受所提供参数的'<='的重载

5个回答

58

对于Swift 5,请参见rustylepord的回答.

更新Swift 3:

let letters = CharacterSet.letters
let digits = CharacterSet.decimalDigits

var letterCount = 0
var digitCount = 0

for uni in phrase.unicodeScalars {
    if letters.contains(uni) {
        letterCount += 1
    } else if digits.contains(uni) {
        digitCount += 1
    }
}

(旧版本的 Swift 的先前回答)

一种可能的 Swift 解决方案:

var letterCounter = 0
var digitCount = 0
let phrase = "The final score was 32-31!"
for tempChar in phrase.unicodeScalars {
    if tempChar.isAlpha() {
        letterCounter++
    } else if tempChar.isDigit() {
        digitCount++
    }
}

更新:上述解决方案只适用于ASCII字符集中的字符,即不识别Ä、é或ø作为字母。下面的替代解决方案使用了Foundation框架中的NSCharacterSet,可以根据Unicode字符类测试字符:

let letters = NSCharacterSet.letterCharacterSet()
let digits = NSCharacterSet.decimalDigitCharacterSet()

var letterCount = 0
var digitCount = 0

for uni in phrase.unicodeScalars {
    if letters.longCharacterIsMember(uni.value) {
        letterCount++
    } else if digits.longCharacterIsMember(uni.value) {
        digitCount++
    }
}

更新2:自从Xcode 6 beta 4发布以来,第一种解决方案已经不再适用,因为Swift中的isAlpha()和相关的(仅ASCII)方法已被移除。第二个解决方案仍然适用。


1
@sirab333:isalpha()等函数在C中非常著名,详见https://developer.apple.com/library/ios/documentation/System/Conceptual/ManPages_iPhoneOS/man3/ctype.3.html#//apple_ref/doc/man/3/ctype。因此,我只需要想办法从Swift中使用它们就可以了。但请注意,这仅适用于ASCII字符。它不能识别来自“外语”(如“ä”,“è”或“ø”)的字母。 - Martin R
它将+-视为数字。 - Christian Dietrich
@ChristianDietrich:你确定吗?我的测试并没有证实这一点。 - Martin R
@Gerry:是的,那就是我在我的答案中添加的“更新2:”。 - Martin R
@Warpzit:是的,Swift 3有很多变化。我已经更新了答案,感谢您的反馈。 - Martin R
显示剩余5条评论

5

使用unicodeScalars的值

let phrase = "The final score was 32-31!"
var letterCounter = 0, digitCounter = 0
for scalar in phrase.unicodeScalars {
    let value = scalar.value
    if (value >= 65 && value <= 90) || (value >= 97 && value <= 122) {++letterCounter}
    if (value >= 48 && value <= 57) {++digitCounter}
}
println(letterCounter)
println(digitCounter)

4

对于Swift 5,您可以针对简单字符串执行以下操作,但要注意处理像"1️⃣" ,"④"这样的字符,因为这些字符也会被视为数字。

let phrase = "The final score was 32-31!"

var numberOfDigits = 0;
var numberOfLetters = 0;
var numberOfSymbols = 0;

phrase.forEach {

    if ($0.isNumber) {
        numberOfDigits += 1;
    }
    else if ($0.isLetter)  {
        numberOfLetters += 1
    }
    else if ($0.isSymbol || $0.isPunctuation || $0.isCurrencySymbol || $0.isMathSymbol) {
        numberOfSymbols += 1;
    }
}

print(#"\#(numberOfDigits)  || \#(numberOfLetters) || \#(numberOfSymbols)"#);

1

如果您只需要一个信息(字母、数字或符号),您可以在一行中完成:

let phrase = "The final score was 32-31!"

let count = phrase.filter{ $0.isLetter }.count
print(count) // "16\n"

但是多次执行 phrase.filter 效率较低,因为它需要遍历整个字符串。


0
我为字符串创建了一个简短的扩展,用于字母和数字计数。
extension String {
  var letterCount : Int {
    return self.unicodeScalars.filter({ CharacterSet.letters.contains($0) }).count
  }

  var digitCount : Int {
   return self.unicodeScalars.filter({ CharacterSet.decimalDigits.contains($0) }).count
  }
}

或者编写一个函数来获取输入的任何CharacterSet的计数

extension String {    
  func characterCount(for set: CharacterSet) -> Int {
    return self.unicodeScalars.filter({ set.contains($0) }).count
  }
}

用法:

let phrase = "the final score is 23-13!"
let letterCount = phrase.characterCount(for: .letters)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接