0

I have constructed the following Regex, which allows strings that only satisfy all three conditions:

  1. Allows alphanumeric characters.
  2. Allows special characters defined in the Regex.
  3. String length must be min 8 and max 20 characters.

The Regex is:

"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&])[A-Za-z\d$@$!%*?&]$"

I use the following Javascript code to verify input:

var regPassword = new RegExp("^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&])[A-Za-z\d$@$!%*?&]$");

regPassword.test(form.passwordField.value);

The test() method returns false for such inputs as abc123!ZXCBN. I have tried to locate the problem in the Regex without any success. What causes the Regex validation to fail?

3
  • Your first two requirements ("Allows only alphanumeric characters" and "Allows only special characters defined in the Regex") are clearly at odds: a string that contains only alphanumeric characters cannot contain any special characters. So the only string that satisfies both of those requirements is the empty string, which is ruled out by your third requirement. Commented Feb 14, 2016 at 19:22
  • Good point! I have reformulated the question description. Commented Feb 14, 2016 at 19:27
  • It's totally trivial to write a regex that does what you want, e.g. /^[a-z0-9!@#$%]{8,20}$/i. But I have to ask: why so fixated on using specifically a single regex that is de facto beyond your current skill level? That would only make your code harder to understand, debug, and maintain. Commented Feb 14, 2016 at 19:35

1 Answer 1

1

I see two major problems. One is that inside a string "...", backslashes \ have a special meaning, independent of their special meaning inside a regex. In particular, \d ends up just becoming d — not what you want. The best fix for that is to use the /.../ notation instead of new RegExp("..."):

var regPassword = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&])[A-Za-z\d$@$!%*?&]$/;

The other problem is that your regex doesn't match your requirements.

Actually, the requirements that you've stated don't really make sense, but I'm guessing you want something like this:

  1. Must contain at least one lowercase letter, at least one uppercase letter, at least one digit, and at least one of the special characters $@$!%*?&.
  2. Can only contain lowercase letters, uppercase letters, digits, and the special characters $@$!%*?&.
  3. Total length must be between 8 and 20 characters, inclusive.

If so, then you've managed #1 and #2, but forgot about #3. Right now your regex demands that the length be exactly 1. To fix this, you need to add {8,20} after the [A-Za-z\d$@$!%*?&] part:

var regPassword = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&])[A-Za-z\d$@$!%*?&]{8,20}$/;
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the reformulation of the question and the answer! I had actually the length defined in my code, but copied some old Regex I was testing. The problem was that I was creating Regex object with the string above. Your way of defining the Regex has solved the problem!

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.