0

I am in the process of developing a registration form. It has the following requirements:

  • can contain uppercase and capital letters, numbers, and character set
  • must not contain spaces
  • length from 5 to 16 characters

I will check the string like this.

extension String {

    var isValidUsername: Bool {
        let predicate = NSPredicate(format: "SELF MATCHES %@ ", "^(?=.*[A-Za-z0-9!@#$%^&*()._-]).{5,16}$")

        return predicate.evaluate(with: self)
    }

}

Now there are 2 problems I can enter the spaces, although I should not. I can use characters other than those listed. How do I fix this?

V. Khuraskin
  • 79
  • 1
  • 10

1 Answers1

1

Actually, a regex still can be used here as there are only two things to fix:

  • The . pattern used at the end of the regex matches any char but a line break char hence it can match really a lot of chars
  • The lookahead (?=.*[A-Za-z0-9!@#$%^&*()._-]) just requires at least one char listed in the character class after any zero or more chars other than line break chars. To only allow chars from the lookahead, use the lookahead character class instead of . in the consuming pattern.

NOTE the anchors are redundant since MATCHES requires a full string match.

You can fix the code with

extension String {
    var isValidUsername: Bool {
        let predicate = NSPredicate(format: "SELF MATCHES %@ ", "[A-Za-z0-9!@#$%^&*()._-]{5,16}")
        return predicate.evaluate(with: self)
    }
}
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563