1

I have a Regex to validate a password: at least one uppercase, one lowercase, one number and one special character:

^(?=[^a-z]*[a-z])(?=[^A-Z]*[A-Z])(?=\D*\d)(?=.*[$@$!%*?&,;.:-_])[A-Za-z\d$@$!%*?&,;.:-_]+

But I also want to allow empty because I will validate it in another way.

So I tried to options:

^((?=[^a-z]*[a-z])(?=[^A-Z]*[A-Z])(?=\D*\d)(?=.*[$@$!%*?&,;.:-_])[A-Za-z\d$@$!%*?&,;.:-_]+)*$

NOTE: I wrapped the Regex in () and added *$ at the end;

Or the following:

^$|(?=[^a-z]*[a-z])(?=[^A-Z]*[A-Z])(?=\D*\d)(?=.*[$@$!%*?&,;.:-_])[A-Za-z\d$@$!%*?&,;.:-_]+

NOTE: Added $| at start ...

What is the best approach? One of these 2 or some other?

6
  • I tried your approach before but when I use ^[A-Za-z0-9]*|$ to allow only alphanumeric and empty this allows Spaces and I have no idea why Commented Apr 19, 2016 at 11:41
  • Use an optional non-capturing group around the whole pattern between the anchors ^(?:...)?$ Commented Apr 19, 2016 at 11:43
  • ^$|^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&,;.:_-])[\w$@$!%*?&,;.:-]+$ should work fine. Commented Apr 19, 2016 at 11:44
  • @WiktorStribiżew Do you mean: ^(?:(?=[^a-z]*[a-z])(?=[^A-Z]*[A-Z])(?=\D*\d)(?=.*[$@$!%*?&,;.:-])[A-Za-z\d$@$!%*?&,;.:-]+)?$ Commented Apr 19, 2016 at 11:53
  • @anubhava why the $ after the + at the end? Would $| at start be enough? Commented Apr 19, 2016 at 11:55

1 Answer 1

1

If you have a regex matching at least something, but not the whole string, you need to use an alternation with $:

^(?:(?=[^a-z]*[a-z])(?=[^A-Z]*[A-Z])(?=\D*\d)(?=.*[$@$!%*?&,;.:_-])[A-Za-z\d$@$!%*?&,;.:_-]+|$)
^^^^                                                                                        ^^^

See the regex demo. Look:

  • ^ - start of string
  • (?: - An alternation group start
    • (?=[^a-z]*[a-z])(?=[^A-Z]*[A-Z])(?=\D*\d)(?=.*[$@$!%*?&,;.:_-])[A-Za-z\d$@$!%*?&,;.:_-]+ - match this
    • | - or...
    • $ - end of string.
  • ) - end of the alternation

If you had a pattern that matched the whole string (say, ^\d+\s+\w+$ to match strings like 12 Apr), and you would like to also match an empty string, you could just enclose with an optional pattern:

^(?:\d+\s+\w+)?$
 ^^^         ^^

Details:

  • ^ - start of string
  • (?:\d+\s+\w+)? - one or zero sequences of 1+ digtis followed with 1+ whitespaces followed with 1+ alphanumerics/underscores
  • $ - end of string
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.