Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regex doesn't recognize underscore as special character

Tags:

regex

/(?=^.{8,}$)(?=.*[_!@#$%^&*-])(?=.*\d)(?=.*\W+)(?![.\n])(?=.*[a-z])(?=.*[A-Z]).*$/

I'm trying to make a regex for password validation such that the password must be at least 8 chars and include one uppercase, one lowercase, one number, and one special char. It works fine except it won't recognize the underscore (_) as a special character. I.e., Pa$$w0rd matches, but Pass_w0rd doesn't. Thoughts?

like image 277
user1436111 Avatar asked Jun 04 '12 21:06

user1436111


4 Answers

This portion of the regex seems to be looking for special characters:

(?=.*[!@#$%^&*-])

Note that the character class does not include an underscore, try changing this to the following:

(?=.*[_!@#$%^&*-])

You will also need to modify or remove this portion of the regex:

(?=.*\W+)

\W is equivalent to [^a-zA-Z0-9_], so if an underscore is your only special character this portion of the regex will cause it to fail. Instead, change it to the following (or remove it, it is redundant since you already check for special characters earlier):

(?=.*[^\w_])

Complete regex:

/(?=^.{8,}$)(?=.*[_!@#$%^&*-])(?=.*\d)(?=.*[^\w_])(?![.\n])(?=.*[a-z])(?=.*[A-Z]).*$/
like image 78
Andrew Clark Avatar answered Nov 27 '22 21:11

Andrew Clark


A much simpler regex that works for you is this:

/(?=.*[_!@#$%^&*-])(?=.*\d)(?!.*[.\n])(?=.*[a-z])(?=.*[A-Z])^.{8,}$/

There were few mistakes in your original regex eg:

  • You don't need to use lookahead for making sure there are 8 chars in input
  • negative lookahead [.\n] was missing .*
  • (?=.*\W+) is superfluous and probably not serving any purpose
like image 43
anubhava Avatar answered Nov 27 '22 22:11

anubhava


This one here works as well. It defines a special character as by excluding alphanumerical characters and whitespace, so it includes the underscore:

(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[\d])(?=.*?[^\sa-zA-Z0-9]).{8,}
like image 20
Anytoe Avatar answered Nov 27 '22 22:11

Anytoe


The problem is that the only thing that could possibly satisfy the \W, by definition, is something other than [a-zA-Z0-9_]. The underscore is specifically not matched by \W, and in Pass_w0rd, nothing else is matched by it, either.

I suspect that having both your specific list of special characters and the \W is overkill. Pick one and you're likely to be happier. I also recommend splitting this whole thing up into several separate tests for much better maintainability.

like image 36
Jan Krüger Avatar answered Nov 27 '22 22:11

Jan Krüger