Angular reactive forms pattern validator adding $ to regex and breaking validation

23,777

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.
Share:
23,777
AvailableName
Author by

AvailableName

BY DAY: I write all kinds of code at the whim of my boss. Often jumping language and technology between tasks. BY NIGHT: I raise kids and read everything I can get my hands on regarding science and technology.

Updated on February 20, 2020

Comments

  • AvailableName
    AvailableName about 4 years

    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:

    • Test1234
    • tEst1234
    • tesT1234
    • 1234Test
    • 1234tesT
    • t#St1234

    Passwords that should fail:

    • TEST1234
    • test1234
    • tEst123
    • Test123
    • testtest
    • 12345678

    Validator declaration:

    this.password = new FormControl('', [Validators.required, Validators.pattern('^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.{8,})')]);
    this.userForm.addControl('Password', this.password);
    
  • AvailableName
    AvailableName almost 6 years
    Changing the length lookahead to a consuming pattern solved it. Thanks.
  • Jignesh Mistry
    Jignesh Mistry over 5 years
    Can i assign this dynamically i mean (?=[^A-Z]*[A-Z]) this code validates for 1 upper case letter what if i want 2 uppercase letters ?
  • Wiktor Stribiżew
    Wiktor Stribiżew over 5 years
    @JigneshMistry Replace (?=[^A-Z]*[A-Z]) with (?=(?:[^A-Z]*[A-Z]){2})
  • Jignesh Mistry
    Jignesh Mistry over 5 years
    Thanks buddy it worked :) Just one more trouble can u send the regex for 2 Numeric & 2 special characters ?
  • Wiktor Stribiżew
    Wiktor Stribiżew over 5 years
    @JigneshMistry They are formed the same way as above.
  • Jignesh Mistry
    Jignesh Mistry over 5 years
    regex for special characters is not mentioned above
  • Wiktor Stribiżew
    Wiktor Stribiżew over 5 years
    @JigneshMistry What chars do you consider special? Anyway, still, it will be formed the same way: (?=(?:[^special_chars]*[special_chars]){2})
  • Jignesh Mistry
    Jignesh Mistry over 5 years
    ! @ # $ % ^ & * ( ) - all these i am considering as special characters
  • Wiktor Stribiżew
    Wiktor Stribiżew over 5 years
    @JigneshMistry So, I guess there is no problem with that. (?=(?:[^!@#$%^&*()]*[!@#$%^&*()]){2})
  • Jignesh Mistry
    Jignesh Mistry over 5 years
    Angular is throwing this error after puting special characters ERROR SyntaxError: Invalid regular expression: /^(?=(?:[^!@#$%^&*()]*[!@#$%^&*()]){2})(?=(?:[^A-Z]*[A-Z]){1‌​})(?:[^!-0]*[!-0]){2‌​})(?=(?:[^0-9]*[0-9]‌​){1}).{8,}$/: Unmatched ')'
  • Wiktor Stribiżew
    Wiktor Stribiżew over 5 years