Question

^(?=(.*\d){4,})(?=(.*[A-Z]){3})(?!\s)(?=.*\W{2,})(?=(.*[a-z]){2,}).{12,14}$

The RegExp above is trying to:

  • match at least 4 digits - (?=(.*\d){4,})
  • match exactly 3 upper case letters - (?=(.*[A-Z]){3})
  • don't match spaces - (?!\s)
  • match at least 2 non-word characters - (?=.*\W{2,})
  • match at least 2 lower - (?=(.*[a-z]){2,})
  • string must be between 12 and 14 in length - .{12,14}

But I am having a challenge getting this to avoid matching spaces. It seems like because \W also includes spaces, my preceding negative look-ahead on spaces is being ignored.

For example:

  • b4A@Ac33*8Pd -- should match
  • b4A@Ac3 3*8Pd -- should not match

rubular link

Edited to provide further clarification:

Basically, I am trying to avoid having to spell out all the characters in the POSIX [:punct:] class ie !"#$%&'()*+,./:;<=>?@\^_\{|}~-` .. that is why I had a need to use \W .. But I would also want to exclude spaces

I can use a second pair of eyes, and more experienced suggestions here ..

Edited again, to correct mix-ups in counts specified in sub-patterns, as pointed out in the accepted answer below.

Was it helpful?

Solution

Instead of using dot ., use non spaces \S:

^(?=(.*\d){3,})(?=(.*[A-Z]){2})(?=.*\W{1,})(?=(.*[a-z]){1,})\S{12,14}$
//                                                  here ___^^

And is this a typo match at least 4 digits - (?=(.*\d){3,}), it should be:

match at least 3 digits - (?=(.*\d){3,})

or

match at least 4 digits - (?=(.*\d){4,})

Same for other counts.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top