2

I'm trying to make a nickname validator. Here are the rules I want:

  • Total character count must be between 3 and 15
  • There can be two non-consecutive spaces
  • Only letters (a-z) are allowed
  • Each word separated by a space can begin with an uppercase letter, the rest of the word must be lowercase
  • At least one of the words must have 3 or more characters

This is what I currently have which checks the four first rules, but I have no idea how to check the last rule.

^(?=.{3,15}$)(\b[A-Z]?[a-z]* ?\b){1,3}$

Should match:

  • Yaw
  • yaw
  • James Bond
  • Monkey D Luffy
  • List item

Shouldn't match:

  • YaW
  • Two spaces (with two consecutive space characters)
  • No no no
  • JamesBond
L. Scott Johnson
  • 3,615
  • 1
  • 13
  • 25
YaW
  • 12,012
  • 3
  • 17
  • 21

2 Answers2

2

Try Regex: ^(?=[A-Za-z ]{3,15}$)(?=[A-Za-z ]*[A-Za-z]{3})(?:\b[A-Z]?[a-z]*\ ?\b){1,3}$

Demo

For the last rule, a positive lookahead without space was used (?=[A-Za-z ]*[A-Za-z]{3})

YaW
  • 12,012
  • 3
  • 17
  • 21
Matt.G
  • 3,363
  • 2
  • 7
  • 21
  • That's really great. Why have you split the words check in two? One with the space and another one without it? I've tried deleting the last group and changing {1,2} to {1,3} and aparently it's the same because the \b wouldn't allow you to end with a space. – YaW Jul 23 '18 at 17:01
  • @YaW, you are right, that is not necessary. feel free to edit the answer that worked for you. – Matt.G Jul 23 '18 at 17:07
0

but I have no idea how to check the last rule

As you only allow [A-Za-z] and space in your regex, you could simply use (?=.*?\S{3}) which looks ahead for 3 non white-space characters. .*? matches lazily any amount of any characters.

As soon as 3 non white-space characters are required the initial lookahead can be improved to the negative ^(?!.{16}) as the minimum of 3 is already required in \S{3}[A-Za-z][a-z]*

Further you can drop the initial \b which is redundant as there can only be start or space before.

^(?!.{16})(?=.*?\S{3})(?:[A-Za-z][a-z]* ?\b){1,3}$

Here is a demo at regex101 (for more regex info see the SO regex faq)

If your tool supports atomic groups, improve performance by use of (?> instead of (?:

bobble bubble
  • 11,968
  • 2
  • 22
  • 34