Regex for validating password requirements

Jacob Lepley
Jacob Lepley used Ask the Experts™
on
I need some regex help. I am currently using the following regex "^(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z])(?=.*[^a-zA-Z])\S{8,20}$" (without the quotes) to validate a password that would require an upper, lower and non-alpha character. I need regex to meet the following criteria:

The password contains characters from three of the following categories:

Uppercase letters
Lowercase letters
Base 10 digits (0 through 9)
Non-alphanumeric characters (special characters): (~!@#$%^&*_-+=`|\(){}[]:;"'<>,.?/) Currency symbols such as the Euro or British Pound are not counted as special characters for this policy setting.
Any Unicode character that is categorized as an alphabetic character but is not uppercase or lowercase. This includes Unicode characters from Asian languages.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Terry WoodsIT Guru
Most Valuable Expert 2011
Commented:
I'm not sure about the part of the pattern for the unicode characters. I've added a placeholder to the pattern for that part.

I've assumed you still want from 8 to 20 non-space characters.

The components of the pattern are as follows:

Uppercase letters:
(?=.*[A-Z])

Open in new window


Lowercase letters:
(?=.*[a-z])

Open in new window


Base 10 digits (0 through 9):
(?=.*\d)

Open in new window


Non-alphanumeric characters (special characters): (~!@#$%^&*_-+=`|\(){}[]:;"'<>,.?/) Currency symbols such as the Euro or British Pound are not counted as special characters for this policy setting. :
(?=.*[\"\^\-\]\\~!@#$%&*_+=`|(){}[:;'<>,.?/])

Open in new window

(note that I've put the characters that need escaping at the start of the character set, to help make it clear what's been escaped)

Any Unicode character that is categorized as an alphabetic character but is not uppercase or lowercase. This includes Unicode characters from Asian languages. :
(?=.*[unicode])

Open in new window

(placeholder... someone else might be able to help with this)

These patterns would be better tested individually, rather than in a single regular expression pattern. However, if you must have a single pattern, then it would be structured like this to cover all the possible combinations:

^(
(p1)(p2)(p3)|
(p1)(p2)(p4)|
(p1)(p2)(p5)|
(p1)(p3)(p4)|
(p1)(p3)(p5)|
(p1)(p4)(p5)|
(p2)(p3)(p4)|
(p2)(p3)(p5)|
(p2)(p4)(p5)|
(p3)(p4)(p5)
)\S{8,20}$

Open in new window


This gives the following pattern:

^(
(?=.*[A-Z])(?=.*[a-z])(?=.*\d)|
(?=.*[A-Z])(?=.*[a-z])(?=.*[\"\^\-\]\\~!@#$%&*_+=`|(){}[:;'<>,.?/])|
(?=.*[A-Z])(?=.*[a-z])(?=.*[unicode])|
(?=.*[A-Z])(?=.*\d)(?=.*[\"\^\-\]\\~!@#$%&*_+=`|(){}[:;'<>,.?/])|
(?=.*[A-Z])(?=.*\d)(?=.*[unicode])|
(?=.*[A-Z])(?=.*[\"\^\-\]\\~!@#$%&*_+=`|(){}[:;'<>,.?/])(?=.*[unicode])|
(?=.*[a-z])(?=.*\d)(?=.*[\"\^\-\]\\~!@#$%&*_+=`|(){}[:;'<>,.?/])|
(?=.*[a-z])(?=.*\d)(?=.*[unicode])|
(?=.*[a-z])(?=.*[\"\^\-\]\\~!@#$%&*_+=`|(){}[:;'<>,.?/])(?=.*[unicode])|
(?=.*\d)(?=.*[\"\^\-\]\\~!@#$%&*_+=`|(){}[:;'<>,.?/])(?=.*[unicode])
)\S{8,20}$

Open in new window


I've added linebreaks to the pattern for clarity. You need to remove those in the actual implementation.

Also, depending on the language, you may need to add additional escaping of characters such as backslashes, dollar signs, and single or double quotes
Jacob LepleyBusiness Systems Programming Analyst

Author

Commented:
Thanks Terry!
So if I wanted to test without the unicode it would look something like this?

^((?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[\"\^\-\]\\~!@#$%&*_+=`|(){}[:;'<>,.?/])(?=.*[A-Z])(?=.*\d)(?=.*[\"\^\-\]\\~!@#$%&*_+=`|(){}[:;'<>,.?/])(?=.*[a-z])(?=.*\d)(?=.*[\"\^\-\]\\~!@#$%&*_+=`|(){}[:;'<>,.?/]))\S{8,20}$
IT Guru
Most Valuable Expert 2011
Commented:
I think you've missed the alternation character, which is a pipe character. It works like this:
matchThis|orThisInstead|orThis

Open in new window


If I assume your pattern is otherwise correct, that would mean your pattern would be:
^((?=.*[A-Z])(?=.*[a-z])(?=.*\d)|(?=.*[A-Z])(?=.*[a-z])(?=.*[\"\^\-\]\\~!@#$%&*_+=`|(){}[:;'<>,.?/])|(?=.*[A-Z])(?=.*\d)(?=.*[\"\^\-\]\\~!@#$%&*_+=`|(){}[:;'<>,.?/])|(?=.*[a-z])(?=.*\d)(?=.*[\"\^\-\]\\~!@#$%&*_+=`|(){}[:;'<>,.?/]))\S{8,20}$ 

Open in new window

Jacob LepleyBusiness Systems Programming Analyst

Author

Commented:
Apologies I had a baby and been off for a couple weeks. The solutions helped. Thank you.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial