'Check if a String is alphanumeric in Swift
In Swift, how can I check if a String is alphanumeric, ie, if it contains only one or more alphanumeric characters [a-zA-Z0-9], excluding letters with diacritics, eg, é.
Solution 1:[1]
extension String {
var isAlphanumeric: Bool {
return !isEmpty && range(of: "[^a-zA-Z0-9]", options: .regularExpression) == nil
}
}
"".isAlphanumeric // false
"abc".isAlphanumeric // true
"123".isAlphanumeric // true
"ABC123".isAlphanumeric // true
"iOS 9".isAlphanumeric // false
Solution 2:[2]
A modern Swift 3 and 4 solution
extension String {
func isAlphanumeric() -> Bool {
return self.rangeOfCharacter(from: CharacterSet.alphanumerics.inverted) == nil && self != ""
}
func isAlphanumeric(ignoreDiacritics: Bool = false) -> Bool {
if ignoreDiacritics {
return self.range(of: "[^a-zA-Z0-9]", options: .regularExpression) == nil && self != ""
}
else {
return self.isAlphanumeric()
}
}
}
Usage:
"".isAlphanumeric() == false
"Hello".isAlphanumeric() == true
"Hello 2".isAlphanumeric() == false
"Hello3".isAlphanumeric() == true
"Français".isAlphanumeric() == true
"Français".isAlphanumeric(ignoreDiacritics: true) == false
This works with languages other than English, allowing diacritic characters like è and á, etc. If you'd like to ignore these, use the flag "ignoreDiacritics: true".
Solution 3:[3]
I felt the accepted answer using regex was concrete but a rather heavy solution. You could check it this way also in Swift 3.0:
if yourString.rangeOfCharacter(from: CharacterSet.alphanumerics.inverted) != nil {
return "Username can only contain numbers or digits"
}
Solution 4:[4]
extension String {
/// Allows only `a-zA-Z0-9`
public var isAlphanumeric: Bool {
guard !isEmpty else {
return false
}
let allowed = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
let characterSet = CharacterSet(charactersIn: allowed)
guard rangeOfCharacter(from: characterSet.inverted) == nil else {
return false
}
return true
}
}
XCTAssertFalse("".isAlphanumeric)
XCTAssertFalse("climate change".isAlphanumeric)
XCTAssertFalse("Poüet".isAlphanumeric)
XCTAssertTrue("Hawking2018".isAlphanumeric)
Solution 5:[5]
The problem with the CharacterSet.alphanumerics CharacterSet is that it is more permissive than [a-zA-Z0-9]. It contains letters with diacritics, Eastern Arabic numerals, etc.
assert(["e", "E", "3"].allSatisfy({ CharacterSet.alphanumerics.contains($0) }))
assert(["ê", "É", "?"].allSatisfy({ CharacterSet.alphanumerics.contains($0) }))
You can build your own CharacterSet using only the specific 62 "alphanumeric" characters:
extension CharacterSet {
static var alphanumeric62: CharacterSet {
return lowercase26.union(uppercase26).union(digits10)
}
static var lowercase26: CharacterSet { CharacterSet(charactersIn: "a"..."z") }
static var uppercase26: CharacterSet { CharacterSet(charactersIn: "A"..."Z") }
static var digits10: CharacterSet { CharacterSet(charactersIn: "0"..."9") }
}
assert(["e", "E", "3"].allSatisfy({ CharacterSet.alphanumeric62.contains($0) }))
assert(["ê", "É", "?"].allSatisfy({ CharacterSet.alphanumeric62.contains($0) == false }))
Then test your string against the inverse of that CharacterSet:
guard "string".rangeOfCharacter(from: CharacterSet.alphanumeric62.inverted) == nil else {
fatalError()
}
Solution 6:[6]
This regex used to check that string contains atleast 1 alphabet + atleast 1 digit alongwith 8 characters.
"^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{8,}$"
Solution 7:[7]
extension String {
var isAlphaNumeric: Bool {
let hasLetters = rangeOfCharacter(from: .letters, options: .numeric, range: nil) != nil
let hasNumbers = rangeOfCharacter(from: .decimalDigits, options: .literal, range: nil) != nil
let comps = components(separatedBy: .alphanumerics)
return comps.joined(separator: "").count == 0 && hasLetters && hasNumbers
}
}
Solution 8:[8]
Here's a succinct approach:
extension String {
var isAlphanumeric: Bool {
allSatisfy { $0.isLetter || $0.isNumber }
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 | carbonr |
| Solution 4 | neoneye |
| Solution 5 | pkamb |
| Solution 6 | Uma Madhavi |
| Solution 7 | Sathish Kumar Gurunathan |
| Solution 8 | rmp251 |
