How can I validate a name field to allow only one space, and begin and end with a letter in PHP?

I'm looking for a regex in PHP that can do the following for me:

I have a name field for a person's first name. I'd like to allow for the person to actually input two names in the first name field. Each name must begin with a capital letter, end with a letter, and may include a single quote, or a dash, if necessary. One space is allowed in between the names. The following names would be acceptable:

Steven O'Reilly
James Dean Peterson
James-Dean Peterson
James Dean-Peterson

Two names in the first name field are not required, but it would be allowed. Here is a regex I've been playing with:

if(!preg_match('/^[A-Z][a-z-]+[a-z]+([\s][A-Z][a-z-]+[a-z])?$/', $fname))

This allows me to have two names in the field that begin with a capital letter, and end with a lowercase. It also allows me to have a dash (-), but I can't get it to allow a single quote ('). It also allows multiple spaces at the end of the names, assuming there are no other letters. I can eliminate that with a trim() function, so no big deal, but if I could make it invalid with the regex that would be great.

Anyway, can anyone offer a regex that allows the single quotes, and makes any spaces after the last letter not allowed?

Upvotes: 0

Views: 5794

Answers (2)

For anyone who may run into this issue, I discovered my issue. The regex stands, but needs a couple of additional characters.

if(!preg_match('/^[A-Z][a-z-\']+[a-z]+([\s][A-Z][a-z-\']+[a-z])?$/', $fname))

The one thing I didn't do was strip the slashes from the $fname variable before checking it. So, just use the stripslashes() function on your variable, then check it against this. To eliminate the additional spaces (if there are any) just use trim(). Simple enough.

Upvotes: 0

Stephane Gosselin
Stephane Gosselin

Reputation: 9148

Although full regex validation is possible, doing it this way is painful for you, and cumbersome for your poor users. You may get names in all caps, for example. I always favor the approach of saving the user name in db as is, and on output, format it the way I want. In your case it would maybe look like this:

$name = 'john doe';

$fullname = htmlspecialchars(trim(explode(" ", $name), ENT_QUOTES));

$firstName = ucfirst($fullname[0]);
$lastName  = ucfirst($fullname[1]);

This is just a vague idea of how I would approach this.

To trim your string with a regex this may help you too:

  //Trim whitespace (including line breaks) at the start and the end of the string
  preg_replace("\A\s+|\s+\z", "", $text);

For your quotes, say you want to allow both single or double quotes, this block ['"] matches on quotes add it in your regex to match only once anywhere after second letter, for example.

Upvotes: 1

Related Questions