-4

I have tried lots of regex patterns but I couldn't find a perfect regex which does the following (min. 3 char and max. 30, special characters can be allowed, if all characters are only special characters it should return false).

Expectation:

  1. "ben":true,(3 char satisfied)
  2. "ab":false, (3 char not satisfied)
  3. "ben franklin":true, (space can be allowed)
  4. "ben_franklin":true, (special char can be allowed)
  5. "ben@:true, (special char and min 3 char satisfied)
  6. "%#$":false, (though 3char ,but its all special char)
  7. "ben#franklin":true,
  8. "be'franklin":true
  9. "&%^$@#!*&^":false
  • I suppose if you have 10 special chars in a row it's also false? `"&%^$@#!*&^":false`? – xdhmoore Nov 14 '20 at 03:47
  • @xdhmoore yup it should be false – Ben Franklin Nov 14 '20 at 03:49
  • 1
    is it required that you solve it with only one regex? if you split the task into two regexes, the problem becomes much easier. Whitelist first ( check if it has only the characters that you want and in the desired length ) and accept them, then blacklist second ( check if the string only contains special characters ) and reject those – tsamridh86 Nov 14 '20 at 03:53
  • @SamridhTuladhar that is what I was also going to suggest. – xdhmoore Nov 14 '20 at 03:55

2 Answers2

5

If by "special characters", you mean any non-alphanumeric characters, you may use the following pattern:

^(?=.*[A-Za-z0-9]).{3,30}$

Demo.

Breakdown:

^                   # Beginning of the string.
(?=.*[A-Za-z0-9])   # Must contain at least one alphanumeric (English) character.
.{3,30}             # Match any character (special or not) between 3 and 30 times.
$                   # End of string.

Further adjustments:

  • If you want to add more characters to the "not special chars", you may add them inside the character class. For example, to add the space char, you may use [A-Za-z0-9 ].

  • If you want to limit the "special characters" to a particular set of characters, then you may replace .{3,30} with [A-Za-z0-9@#$%....]{3,30}.

0

I would probably just do this with 2 passes:

let str = "ben#franklin";
let result = !!(str.match(/^[a-z\s!@#$%^&_-]{3,30}$/g) && str.match(/^.*[a-z].*$/g));
console.log(result);
  1. Check for valid characters.
  2. Make sure at least one a-z character.

You didn't mention numbers or uppercase characters, so I didn't add them.

xdhmoore
  • 8,935
  • 11
  • 47
  • 90