Depending on the exact requirements, RegEx may be the better route.
- Are leading / trailing / extra spaces valid?
- Are extended Latin characters valid?
- Are punctuated names valid (hyphenated or apostrophes)?
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 黒澤明]