Home > Enterprise >  Am I implementing negative lookaheads correctly with my regex?
Am I implementing negative lookaheads correctly with my regex?

Time:12-02

I'm a beginner with regex and stuck with creating regex with the following conditions:

  • Minimum of 8 characters
  • Maximum of 60 characters
  • Must contain 2 letters
  • Must contain 1 number
  • Must contain 1 special character
  • Special character cannot be the following: & ` ( ) = [ ] | ; " ' < >

So far I have the following...

(?=^.{8,60}$)(?=.*\d)(?=[a-zA-Z]{2,})(?!.*[&`()=[|;"''\]'<>]).*

But my last two tests are failing and I have no idea why...

  1. !@#$%^* -_~?,.{}!HR12345
  2. 123456789AB!

If you'd like to see my test and expected results, visit here: https://regexr.com/73m2o

My tests contains acceptable number of characters, appropriate number of alphabetic characters, and supported special characters... I don't know why it's failing!

CodePudding user response:

Part of the issue is that you're missing the .* in (?=[a-zA-Z]{2,}). However, your implementation of "two or more" letters is not correct unless the letters must be consecutive.

You'll see that the string 1234567B89A! fails to match, even with the correction. You can fix this like so:

(?=^.{8,60}$)(?=.*\d)(?=.*[a-zA-Z].*[a-zA-Z])(?!.*[&`()=[|;"''\]'<>]).*

The part I changed is (?=.*[a-zA-Z].*[a-zA-Z]) asserting that we can match a letter, zero or more other characters, and then another letter.

https://regex101.com/r/jEsK0S/1

Also, there's currently no assertion that there must be a special character, only an assertion of which ones shouldn't match. So I'd suggest adding another lookahead with a list of valid special characters.

CodePudding user response:

Since the 2 alphabetical characters can appear anywhere in the string, you need to prepend your check for them with .* (as you have with the other character classes you're checking for); otherwise the positive lookaheads will, in this scenario, try to assert their appearance at the beginning of the string (position 0):

(?=^.{8,60}$)(?=.*\d)(?=.*[a-zA-Z]{2,})(?!.*[&`()=[|;"''\]'<>]).*
  • Related