0

I am trying to write a regex for a string that will be a person's name. These are the following restrictions:

  • Can contain at most 1 - symbol (can be none)
  • Can contain at most 1 ' symbol (can be none)
  • There cannot be two spaces next to each other
  • A space must be proceeded and followed by a letter (a-z or A-Z)
  • There is a max of 20 characters for the string
  • The string must start with a letter (a-z or A-Z)

This is the expression I have so far:

^(?!.*[ ]{2})(?!(.*?-){2})(?!(.*?'){2})([a-zA-Z])([(?<=[a-zA-Z]) (?=[a-zA-Z])][a-zA-Z0-9\-']*){0,19}$

What I am missing is checking to make sure the space is followed and preceded by a letter. Any advice on how to incorporate that is very welcome. Thanks!

Eritrean
  • 15,851
  • 3
  • 22
  • 28
slugkiss
  • 11
  • 1
  • 1
    add a valid positive test case and use https://regex101.com/ – Anmol Parida Apr 26 '21 at 20:02
  • 1
    Perhaps like this `^[a-zA-Z](?!.*(['-]).*\1)(?!.* )(?=.{0,19}$)[a-zA-Z0-9'-]*(?:[a-zA-Z] [a-zA-Z][a-zA-Z0-9'-]*)*$` https://regex101.com/r/UPySgp/1 – The fourth bird Apr 26 '21 at 20:24
  • Or with a lookbehind also allowing `a b` like `^[a-zA-Z](?!.*(['-]).*\1)(?!.* )(?=.{0,19}$)[a-zA-Z0-9'-]*(?:(?<=[a-zA-Z]) [a-zA-Z][a-zA-Z0-9'-]*)*$` https://regex101.com/r/QKXOw0/1 – The fourth bird Apr 26 '21 at 20:41
  • Oh my gosh, thank you for that! It works :) I took out the numbers since those weren't allowed (forgot to mention that rule also) and it is perfect. You made what I wrote better too, so thank you! – slugkiss Apr 26 '21 at 22:47
  • While this can be done with a regular expression, it is maybe clearer and simpler to write some code for the check. – Henry Apr 27 '21 at 09:34

1 Answers1

1

For these specific requirements, you might use:

^[a-zA-Z](?!.*(['-]).*\1)(?!.*  )(?=.{0,19}$)[a-zA-Z0-9'-]*(?: (?<=[a-zA-Z] )[a-zA-Z][a-zA-Z0-9'-]*)*$

The pattern matches:

  • ^ Start of string
  • [a-zA-Z] Match a char a-zA-Z
  • (?!.*(['-]).*\1) Negative lookahead, assert not 2 times ' or - using a capture group with a backreference \1 to match the same what is captured in group 1
  • (?!.* ) Negative lookahead, assert not 2 spaces
  • (?=.{0,19}$) Positive lookahead to assert 0-19 chars as the first char is already matched
  • [a-zA-Z0-9'-]* Optionally match any of the listed without a space
  • (?: Non capture group
    • (?<=[a-zA-Z] )[a-zA-Z] Match a space and assert a char a-zA-Z before it
    • [a-zA-Z0-9'-]* Optionally match any of the listed chars
  • )* Close non capture group and optionally repeat
  • $ End of string

See a regex demo

Or without the numbers

^[a-zA-Z](?!.*(['-]).*\1)(?!.*  )(?=.{0,19}$)[a-zA-Z'-]*(?: (?<=[a-zA-Z] )[a-zA-Z][a-zA-Z'-]*)*$

Regex demo

The fourth bird
  • 154,723
  • 16
  • 55
  • 70