Reputation:
I am currently trying to validate a name input field. For that purpose I would like to check the input.
The input is a string and should only consist of letters and spaces. Is there any simple way to implement it.
For example I have the Input of "Jon Doe"
, how can I verify that this a acceptable name while Peter2
or Ben&Jerry
isnt?
Thanks for your help in advance. <3
Upvotes: 2
Views: 2741
Reputation: 77486
Depending on the exact requirements, RegEx may be the better route.
For example, with this list of "name" entries:
"Jon Doe",
"Ben&Jerry",
"JonDoe",
"Jon Edward Doe",
" Jon Doe",
"Jon Doe",
"Jon Doe ",
"Jon Doe2",
"José Doe",
"Jon O'Doe",
"Jon Doe-Smith",
"Joß Müller",
"Jon 黒澤明"
Which ones should be valid?
EDIT: updated with better (?) RegEx based on Rob's answer...
Using this code, which evaluates the entries with both .rangeOfCharacter
and with a RegEx test:
class ViewController: UIViewController {
override func viewDidLoad() {
let names: [String] = [
"Jon Doe",
"Ben&Jerry",
"JonDoe",
"Jon Edward Doe",
" Jon Doe",
"Jon Doe",
"Jon Doe ",
"Jon Doe2",
"José Doe",
"Jon O'Doe",
"Jon Doe-Smith",
"Joß Müller",
"Jon 黒澤明",
]
names.forEach {
test($0)
}
}
func test(_ text: String) -> Void {
let ss = "^[\\p{L}\\p{P}]+\\s[\\p{L}\\p{P}]+$"
let b1 = text.range(of: ss, options: .regularExpression) != nil
let lettersAndSpacesCharacterSet = CharacterSet.letters.union(.whitespaces).inverted
let b2 = text.rangeOfCharacter(from: lettersAndSpacesCharacterSet) == nil
print("RegEx:", b1, "\t", "Range:", b2, "\t", "[\(text)]")
}
}
The output is:
RegEx: true Range: true [Jon Doe]
RegEx: false Range: false [Ben&Jerry]
RegEx: false Range: true [JonDoe]
RegEx: false Range: true [Jon Edward Doe]
RegEx: false Range: true [ Jon Doe]
RegEx: false Range: true [Jon Doe]
RegEx: false Range: true [Jon Doe ]
RegEx: false Range: false [Jon Doe2]
RegEx: true Range: true [José Doe]
RegEx: true Range: false [Jon O'Doe]
RegEx: true Range: false [Jon Doe-Smith]
RegEx: true Range: true [Joß Müller]
RegEx: true Range: true [Jon 黒澤明]
Upvotes: 0
Reputation: 437622
You have to decide how permissive you want to be. There are common Western exceptions including:
Plus, if you eventually localized the app for other languages, you might want
Regex handles this stuff gracefully, e.g. this is for any letter and a few select punctuation symbols:
let searchString = #"^([\p{L},.'’-]+(\s|$))+"#
if string.range(of: searchString, options: .regularExpression) != nil {
print(string, "passed")
} else {
print(string, "failed")
}
If you don’t want to permit the periods or commas, feel free to remove them from the above regex.
Upvotes: 0
Reputation: 1145
you could also do something like this
func onlyLettersChecker(string: String) -> Bool {
let justLettersRegex = "[^A-Za-zÀ-ÖØ-öø-ÿ]"
let trimmedString = string.replacingOccurrences(of: " ", with: "")
return trimmedString.isEmpty == false && trimmedString.range(of: justLettersRegex, options: .regularExpression) == nil
}
You delete the whitespaces of your string, and then check if there are only letters there.
That regex accepts accents in the names, you might need to modify the regex if you need some apostrophes in your names and so on.
Upvotes: 1
Reputation: 647
let lettersAndSpacesCharacterSet = CharacterSet.letters.union(.whitespaces).inverted
let testValid1 = "Jon Doe".rangeOfCharacter(from: lettersAndSpacesCharacterSet) == nil // true
let testInvalid1 = "Ben&Jerry".rangeOfCharacter(from: lettersAndSpacesCharacterSet) == nil // false
let testInvalid2 = "Peter2".rangeOfCharacter(from: lettersAndSpacesCharacterSet) == nil // false
Upvotes: 13