[Fixed] Validator.pattern(RegEx) not working as I thought it would work

Issue

This is a weird issue and I seem to find nothing about it anywhere. All the regex expressions I find everywhere are like this:

(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[[email protected]#\$%\^&\*])(?=.{8,})

Bue when I pass that on my formControl like this:

'password': new FormControl( this.register.password, [ Validator.pattern('(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[[email protected]#\$%\^&\*])(?=.{8,})') ]

it doesnt validate when when I fullfill all the requirements of the password. Anyone out there that can give me a hand with this? I am new to regex expressions.

Solution

Your validator isn’t working because of the way the pattern(string) is implemented.

Here is the source code for the validator and here is the source code of its internals. The most intesting part for You is the line if (typeof pattern === 'string') which Your code is going through (as You passed a string, not RegExp).

I’ve created a StackBlitz for You (to be honest, You should have created it).

Note how Your regex looks in the 1st example.

Now as You see the difference, it comes down to explain what the RegExp You put in is actualy doing and why it won’t mach never ever.

This entire regexp is one giant positive lookahead which in basic terms means it is not going to march through entire input string, so it will never reach the $ sign (bacause after matching it will forget about this lookahead and go back to 1st non-lookahead character, which is the start of the string), which means the ^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[[email protected]#$%^&*])(?=.{8,})$ will never match.

  • ^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[[email protected]#$%^&*])(?=.{8,})$ – will never match (because it is just looking ahead from the beginning of the string, not ever going to satisfy $),
  • ^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[[email protected]#$%^&*])(?=.{8,}) – will match as we are naturaly starting from the beginning of the string.
  • (?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[[email protected]#$%^&*])(?=.{8,}) – will match any string that have at least 1 small letter, big letter, digit and special character, and it has to be of length more that 7.

Example: link

So to summarize:

  • do not copy something You do not understand and expect it to work,
  • Validators.pattern(string) will add ^ and $ signs at the beginning and the end of the string before converting it to a RegExp
  • to not allow this, just use a Validators.pattern(RegExp)
  • … or just not do it lazy way by using the RegExp which for just a basic 8 character long string will do over 130 steps to validate it.

Leave a Reply

(*) Required, Your email will not be published