I'm trying to validate a password with the following regex:^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.{8,})
.
Note that there is no terminating $
char, because that would prevent valid passwords from being accepted. (I'm not sure why the input field doesn't terminate the string).
However, Angular's Validators.pattern
adds the end of string char. And therefore my valid passwords fail.
How do I prevent the pattern validator from adding the $
?
I suppose I could roll my own password validator, but surely there is a better solution...?
EDIT: Passwords that should succeed:
Passwords that should fail:
Validator declaration:
this.password = new FormControl('', [Validators.required, Validators.pattern('^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.{8,})')]);
this.userForm.addControl('Password', this.password);
To validate a field with a Regex pattern, click the Must match pattern check box. Next, add the expression you want to validate against. Then add the message your users will see if the validation fails. You can save time for your users by including formatting instructions or examples in the question description.
In a reactive form, the source of truth is the component class. Instead of adding validators through attributes in the template, you add validator functions directly to the form control model in the component class. Angular then calls these functions whenever the value of the control changes.
FormBuilder allows us to explicitly declare forms in our components. This allows us to also explicitly list each form control's validators.
You may add a .*
at the end, or even revamp the pattern a bit to convert one lookahead into a consuming pattern:
Validators.pattern('(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).{8,}')
Or, better, when using a regex for password validation, follow the principle of contrast:
Validators.pattern('(?=[^A-Z]*[A-Z])(?=[^a-z]*[a-z])(?=[^0-9]*[0-9]).{8,}')
Angular will add ^
and $
on both ends of the regex pattern, so the pattern will look like
^(?=[^A-Z]*[A-Z])(?=[^a-z]*[a-z])(?=[^0-9]*[0-9]).{8,}$
Note it won't add the anchors automatically if you use a regex literal, add them manually:
Validators.pattern(/^(?=[^A-Z]*[A-Z])(?=[^a-z]*[a-z])(?=\D*\d).{8,}$/)
With a regex literal, you may use single backslashes in regex escapes (/\d/
to match a digit vs. "\\d"
in a string literal).
See the regex demo
Details
^
- start of string(?=[^A-Z]*[A-Z])
- at least 1 uppercase ASCII letter(?=[^a-z]*[a-z])
- at least 1 lowercase ASCII letter(?=[^0-9]*[0-9])
- at least 1 ASCII digit.{8,}
- any 8 or more chars (other than line break chars)$
- end of string.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With