I need to check if a password match the following rules:
- At least 8 characters (lenth)
- One capital letter
- One lower letter
- One number
- One special char
- Can't contain '.' or '_' (tricky part)
For example:
- Bft$ns2E => should match
- H2od%^.,3 => should't match (notice the '.')
I tried this:
^(?=.*?[A-Z])(?=(.*[a-z]){1,})(?=(.*[\d]){1,})(?=(.*[\W]){1,})(?!.*\s).{8,}$
That satisfy all rules, except the last one ( Can't contain '.' or '_'). Regex are always a pain for me and can't figure out how to do this.
Thanks to all!
CodePudding user response:
Your regex is on the right track. I would use:
^(?=.*?[A-Z])(?=.*[a-z])(?=.*\d)(?=.*\W)(?!.*[._]).{8,}$
This pattern says to:
^
(?=.*?[A-Z]) assert capital letter
(?=.*[a-z]) assert lowercase letter
(?=.*\d) assert digit
(?=.*\W) assert non word/special character
(?!.*[._]) assert NO dot or underscore
.{8,} match a password of length 8 or greater
$
CodePudding user response:
Using the lookaheads like this (?=(.*[a-z]){1,})
, you can omit the group with the quantifier {1,}
as asserting it once in the string is enough.
If you don't want to match a space .
or _
you can use a negated character class to match 8 or more times excluding those characters.
Using a negated character class as well in the lookahead assertions prevents unnecessary backtracking.
^(?=[^A-Z\r\n]*[A-Z])(?=[^a-z\r\n]*[a-z])(?=[^\d\r\n]*\d)(?=\w*\W)[^\s._]{8,}$
The pattern matches:
^
Start of string(?=[^A-Z\r\n]*[A-Z])
Assert a char A-Z(?=[^a-z\r\n]*[a-z])
Assert a char a-z(?=[^\d\r\n]*\d)
Assert a digit(?=\w*\W)
Assert a non word char[^\s._]{8,}
Match 8 times any char except a whitespace char.
or-
$
End of string