I’m trying to validate a password using the following regex in JavaScript:
/^(?=.*[a-z])(?=.*[A-Z])(?=.*d)(?=.*[@$!%*?&])[A-Za-zd@$!%*?&]+$/
The validation requirements are:
- At least one lowercase letter
- At least one uppercase letter
- At least one number
- At least one special character
Here is the password validation configuration I use:
password: {
type: "string",
required: "Password is required",
matches: {
regex:
/^(?=.*[a-z])(?=.*[A-Z])(?=.*d)(?=.*[@$!%*?&])[A-Za-zd@$!%*?&]+$/,
message:
"Please include at least one uppercase letter, one lowercase letter, one number, and one special character.",
},
min: {
value: 8,
message: "Password must be at least 8 characters",
},
max: {
value: 20,
message: "Password must not exceed 20 characters",
},
}
However, this regex fails for the string ogJ((48HzpZI.
The string meets all the criteria:
- Contains a lowercase letter (o, g, p, z, i)
- Contains an uppercase letter (J, H, Z, I)
- Contains a digit (4, 8)
- Contains special characters ((, ()
Can anyone help identify why the regex doesn’t pass this string?
I tried validating the password string ogJ((48HzpZI using my regex:
/^(?=.*[a-z])(?=.*[A-Z])(?=.*d)(?=.*[@$!%*?&])[A-Za-zd@$!%*?&]+$/
I expected the validation to pass because the string meets the requirements:
- Contains lowercase letters (o, g, p, z, i)
- Contains uppercase letters (J, H, Z, I)
- Contains digits (4, 8)
- Contains special characters ((, ()
- Is within the required length of 8–20 characters
What happened instead?
The validation failed, and the string did not pass. I’m not sure why the regex isn’t matching the string, even though all the conditions seem to be fulfilled.
2
Answers
The last part of your regex (
[A-Za-zd@$!%*?&]+
) matches only the characters specified within it and there are no parentheses.You should use
.+
instead to match all the characters because the validation has already been done before.I would suggest a few changes to improve your pattern:
p{Ll}
instead of[a-z]
to match a lowercase letter in anylanguage. And use
p{Lu}
instead of[A-Z]
to match an uppercaseletter. You have to enable the unicode flag (or the new v flag).
[](){}|@$£#!%&?+-*/:;,.~"'<>
.than a complicated password.
Example: "I see 3 rabbits & a duck. And you?"
harm your app.
The commented pattern (PCRE flavor):
Here, I replaced the accepted chars by
.{8,20}
, meaning that it willaccept anything. I kept it simple to make the regex short and readable.
The same regex in JavaScript:
Now, a safer version of the regex would be to replace
.
bya white-list of chars. Example, allowing spaces also:
[p{Ll}p{Lu}d [](){}|@$£#!%&?+-*/:;,.~"'<>]{8,64}
Tested with the same JS as before: