[regex] Regular expression for first and last name

For website validation purposes, I need first name and last name validation.

For the first name, it should only contain letters, can be several words with spaces, and has a minimum of three characters, but a maximum at top 30 characters. An empty string shouldn't be validated (e.g. Jason, jason, jason smith, jason smith, JASON, Jason smith, jason Smith, and jason SMITH).

For the last name, it should be a single word, only letters, with at least three characters, but at most 30 characters. Empty strings shouldn't be validated (e.g. lazslo, Lazslo, and LAZSLO).

This question is related to regex validation

The answer is


This seems to do the job for me:

[\S]{2,} [\S]{2,}( [\S]{2,})*

^\p{L}{2,}$

^ asserts position at start of a line.

\p{L} matches any kind of letter from any language

{2,} Quantifier — Matches between 2 and unlimited times, as many times as possible, giving back as needed (greedy)

$ asserts position at the end of a line

So it should be a name in any language containing at least 2 letters(or symbols) without numbers or other characters.


First name would be

"([a-zA-Z]{3,30}\s*)+"

If you need the whole first name part to be shorter than 30 letters, you need to check that seperately, I think. The expression ".{3,30}" should do that.

Your last name requirements would translate into

"[a-zA-Z]{3,30}"

but you should check these. There are plenty of last names containing spaces.


A simple function using preg_match in php

<?php
function name_validation($name) {
    if (!preg_match("/^[a-zA-Z ]*$/", $name) === false) {
        echo "$name is a valid name";
    } else {
        echo "$name is not a valid name";
    }
}

//Test
name_validation('89name');
?>

var name = document.getElementById('login_name').value; 
if ( name.length < 4  && name.length > 30 )
{
    alert ( 'Name length is mismatch ' ) ;
} 


var pattern = new RegExp("^[a-z\.0-9 ]+$");
var return_value = var pattern.exec(name);
if ( return_value == null )
{
    alert ( "Please give valid Name");
    return false; 
} 

There is one issue with the top voted answer here which recommends this regex:

/^[a-z ,.'-]+$/i

It takes spaces only as a valid name!

The best solution in my opinion is to add a negative look forward to the beginning:

^(?!\s)([a-z ,.'-]+)$/i

I've tried almost everything on this page, then I decided to modify the most voted answer which ended up working best. Simply matches all languages and includes .,-' characters.

Here it is:

/^[\p{L} ,.'-]+$/u

Try these solutions, for maximum compatibility, as I have already posted here:

JavaScript:

var nm_re = /^(?:((([^0-9_!¡?÷?¿/\\+=@#$%ˆ&*(){}|~<>;:[\]'’,\-.\s])){1,}(['’,\-\.]){0,1}){2,}(([^0-9_!¡?÷?¿/\\+=@#$%ˆ&*(){}|~<>;:[\]'’,\-. ]))*(([ ]+){0,1}(((([^0-9_!¡?÷?¿/\\+=@#$%ˆ&*(){}|~<>;:[\]'’,\-\.\s])){1,})(['’\-,\.]){0,1}){2,}((([^0-9_!¡?÷?¿/\\+=@#$%ˆ&*(){}|~<>;:[\]'’,\-\.\s])){2,})?)*)$/;

HTML5:

<input type="text" name="full_name" id="full_name" pattern="^(?:((([^0-9_!¡?÷?¿/\\+=@#$%ˆ&*(){}|~<>;:[\]'’,\-.\s])){1,}(['’,\-\.]){0,1}){2,}(([^0-9_!¡?÷?¿/\\+=@#$%ˆ&*(){}|~<>;:[\]'’,\-. ]))*(([ ]+){0,1}(((([^0-9_!¡?÷?¿/\\+=@#$%ˆ&*(){}|~<>;:[\]'’,\-\.\s])){1,})(['’\-,\.]){0,1}){2,}((([^0-9_!¡?÷?¿/\\+=@#$%ˆ&*(){}|~<>;:[\]'’,\-\.\s])){2,})?)*)$" required>


For simplicities sake, you can use:

(.*)\s(.*)

The thing I like about this is that the last name is always after the first name, so if you're going to enter this matched groups into a database, and the name is John M. Smith, the 1st group will be John M., and the 2nd group will be Smith.


As macek said:

Don't forget about names like:

Mathias d'Arras

Martin Luther King, Jr.

Hector Sausage-Hausen

and to remove cases like:

..Mathias

Martin king, Jr.-

This will cover more cases:

^([a-z]+[,.]?[ ]?|[a-z]+['-]?)+$

This is what I use.

This regex accepts only names with minimum characters, from A-Z a-z ,space and -.

Names example:

Ionut Ionete, Ionut-Ionete Cantemir, Ionete Ionut-Cantemirm Ionut-Cantemir Ionete-Second

The limit of name's character is 3. If you want to change this, modify {3,} to {6,}

([a-zA-Z\-]+){3,}\s+([a-zA-Z\-]+){3,}

I'm working on the app that validates International Passports (ICAO). We support only english characters. While most foreign national characters can be represented by a character in the Latin alphabet e.g. è by e, there are several national characters that require an extra letter to represent them such as the German umlaut which requires an ‘e’ to be added to the letter e.g. ä by ae.

This is the JavaScript Regex for the first and last names we use:

/^[a-zA-Z '.-]*$/

The max number of characters on the international passport is up to 31. We use maxlength="31" to better word error messages instead of including it in the regex.

Here is a snippet from our code in AngularJS 1.6 with form and error handling:

_x000D_
_x000D_
class PassportController {_x000D_
  constructor() {_x000D_
    this.details = {};_x000D_
    // English letters, spaces and the following symbols ' - . are allowed_x000D_
    // Max length determined by ng-maxlength for better error messaging_x000D_
    this.nameRegex = /^[a-zA-Z '.-]*$/;_x000D_
  }_x000D_
}_x000D_
_x000D_
angular.module('akyc', ['ngMessages'])_x000D_
  .controller('PassportController', PassportController);
_x000D_
 _x000D_
.has-error p[ng-message] {_x000D_
  color: #bc111e;_x000D_
}_x000D_
_x000D_
.tip {_x000D_
  color: #535f67;_x000D_
}
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js"></script>_x000D_
<script src="https://code.angularjs.org/1.6.6/angular-messages.min.js"></script>_x000D_
_x000D_
<main ng-app="akyc" ng-controller="PassportController as $ctrl">_x000D_
  <form name="$ctrl.form">_x000D_
_x000D_
    <div name="lastName" ng-class="{ 'has-error': $ctrl.form.lastName.$invalid} ">_x000D_
        <label for="pp-last-name">Surname</label>_x000D_
        <div class="tip">Exactly as it appears on your passport</div>_x000D_
        <div ng-messages="$ctrl.form.lastName.$error" ng-if="$ctrl.form.$submitted" id="last-name-error">_x000D_
          <p ng-message="required">Please enter your last name</p>_x000D_
          <p ng-message="maxlength">This field can be at most 31 characters long</p>_x000D_
          <p ng-message="pattern">Only English letters, spaces and the following symbols ' - . are allowed</p>_x000D_
        </div>_x000D_
        _x000D_
        <input type="text" id="pp-last-name" ng-model="$ctrl.details.lastName" name="lastName"_x000D_
               class="form-control" required ng-pattern="$ctrl.nameRegex" ng-maxlength="31" aria-describedby="last-name-error" />_x000D_
      </div>_x000D_
_x000D_
      <button type="submit" class="btn btn-primary">Test</button>_x000D_
_x000D_
  </form>_x000D_
</main>
_x000D_
_x000D_
_x000D_


So, with customer we create this crazy regex:

(^$)|(^([^\-!#\$%&\(\)\*,\./:;\?@\[\\\]_\{\|\}¨?“”€\+<=>§°\d\s¤®™©]| )+$)

For first and last names theres are really only 2 things you should be looking for:

  1. Length
  2. Content

Here is my regular expression:

var regex = /^[A-Za-z-,]{3,20}?=.*\d)/

1. Length

Here the {3,20} constrains the length of the string to be between 3 and 20 characters.

2. Content

The information between the square brackets [A-Za-z] allows uppercase and lowercase characters. All subsequent symbols (-,.) are also allowed.


Don't forget about names like:

  • Mathias d'Arras
  • Martin Luther King, Jr.
  • Hector Sausage-Hausen

This should do the trick for most things:

/^[a-z ,.'-]+$/i

OR Support international names with super sweet unicode:

/^[a-zA-ZàáâäãåacceèéêëeiìíîïlnòóôöõøùúûüuuÿýzzñçcšžÀÁÂÄÃÅACCEEÈÉÊËÌÍÎÏILNÒÓÔÖÕØÙÚÛÜUUŸÝZZÑßÇŒÆCŠŽ?ð ,.'-]+$/u


I use:

/^(?:[\u00c0-\u01ffa-zA-Z'-]){2,}(?:\s[\u00c0-\u01ffa-zA-Z'-]{2,})+$/i

And test for maxlength using some other means


Fullname with only one whitespace:

^[a-zA-Z'\-\pL]+(?:(?! {2})[a-zA-Z'\-\pL ])*[a-zA-Z'\-\pL]+$

If you want the whole first name to be between 3 and 30 characters with no restrictions on individual words, try this :

[a-zA-Z ]{3,30}

Beware that it excludes all foreign letters as é,è,à,ï.

If you want the limit of 3 to 30 characters to apply to each individual word, Jens regexp will do the job.


I have searched and searched and played and played with it and although it is not perfect it may help others making the attempt to validate first and last names that have been provided as one variable.

In my case, that variable is $name.

I used the following code for my PHP:

    if (preg_match('/\b([A-Z]{1}[a-z]{1,30}[- ]{0,1}|[A-Z]{1}[- \']{1}[A-Z]{0,1}  
    [a-z]{1,30}[- ]{0,1}|[a-z]{1,2}[ -\']{1}[A-Z]{1}[a-z]{1,30}){2,5}/', $name)  
    # there is no space line break between in the above "if statement", any that   
    # you notice or perceive are only there for formatting purposes.  
    # 
    # pass - successful match - do something
    } else {
    # fail - unsuccessful match - do something

I am learning RegEx myself but I do have the explanation for the code as provided by RegEx buddy.
Here it is:

Assert position at a word boundary «\b»

Match the regular expression below and capture its match into backreference number 1
«([A-Z]{1}[a-z]{1,30}[- ]{0,1}|[A-Z]{1}[- \']{1}[A-Z]{0,1}[a-z]{1,30}[- ]{0,1}|[a-z]{1,2}[ -\']{1}[A-Z]{1}[a-z]{1,30}){2,5}»

Between 2 and 5 times, as many times as possible, giving back as needed (greedy) «{2,5}»

* I NEED SOME HELP HERE WITH UNDERSTANDING THE RAMIFICATIONS OF THIS NOTE *

Note: I repeated the capturing group itself. The group will capture only the last iteration. Put a capturing group around the repeated group to capture all iterations. «{2,5}»

Match either the regular expression below (attempting the next alternative only if this one fails) «[A-Z]{1}[a-z]{1,30}[- ]{0,1}»

Match a single character in the range between “A” and “Z” «[A-Z]{1}»

Exactly 1 times «{1}»

Match a single character in the range between “a” and “z” «[a-z]{1,30}»

Between one and 30 times, as many times as possible, giving back as needed (greedy) «{1,30}»

Match a single character present in the list “- ” «[- ]{0,1}»

Between zero and one times, as many times as possible, giving back as needed (greedy) «{0,1}»

Or match regular expression number 2 below (attempting the next alternative only if this one fails) «[A-Z]{1}[- \']{1}[A-Z]{0,1}[a-z]{1,30}[- ]{0,1}»

Match a single character in the range between “A” and “Z” «[A-Z]{1}»

Exactly 1 times «{1}»

Match a single character present in the list below «[- \']{1}»

Exactly 1 times «{1}»

One of the characters “- ” «- » A ' character «\'»

Match a single character in the range between “A” and “Z” «[A-Z]{0,1}»

Between zero and one times, as many times as possible, giving back as needed (greedy) «{0,1}»

Match a single character in the range between “a” and “z” «[a-z]{1,30}»

Between one and 30 times, as many times as possible, giving back as needed (greedy) «{1,30}»

Match a single character present in the list “- ” «[- ]{0,1}»

Between zero and one times, as many times as possible, giving back as needed (greedy) «{0,1}»

Or match regular expression number 3 below (the entire group fails if this one fails to match) «[a-z]{1,2}[ -\']{1}[A-Z]{1}[a-z]{1,30}»

Match a single character in the range between “a” and “z” «[a-z]{1,2}»

Between one and 2 times, as many times as possible, giving back as needed (greedy) «{1,2}»

Match a single character in the range between “ ” and “'” «[ -\']{1}»

Exactly 1 times «{1}»

Match a single character in the range between “A” and “Z” «[A-Z]{1}»

Exactly 1 times «{1}»

Match a single character in the range between “a” and “z” «[a-z]{1,30}»

Between one and 30 times, as many times as possible, giving back as needed (greedy) «{1,30}»

I know this validation totally assumes that every person filling out the form has a western name and that may eliminates the vast majority of folks in the world. However, I feel like this is a step in the proper direction. Perhaps this regular expression is too basic for the gurus to address simplistically or maybe there is some other reason that I was unable to find the above code in my searches. I spent way too long trying to figure this bit out, you will probably notice just how foggy my mind is on all this if you look at my test names below.

I tested the code on the following names and the results are in parentheses to the right of each name.

  1. STEVE SMITH (fail)
  2. Stev3 Smith (fail)
  3. STeve Smith (fail)
  4. Steve SMith (fail)
  5. Steve Sm1th (passed on the Steve Sm)
  6. d'Are to Beaware (passed on the Are to Beaware)
  7. Jo Blow (passed)
  8. Hyoung Kyoung Wu (passed)
  9. Mike O'Neal (passed)
  10. Steve Johnson-Smith (passed)
  11. Jozef-Schmozev Hiemdel (passed)
  12. O Henry Smith (passed)
  13. Mathais d'Arras (passed)
  14. Martin Luther King Jr (passed)
  15. Downtown-James Brown (passed)
  16. Darren McCarty (passed)
  17. George De FunkMaster (passed)
  18. Kurtis B-Ball Basketball (passed)
  19. Ahmad el Jeffe (passed)

If you have basic names, there must be more than one up to five for the above code to work, that are similar to those that I used during testing, this code might be for you.

If you have any improvements, please let me know. I am just in the early stages (first few months of figuring out RegEx.

Thanks and good luck, Steve


You make false assumptions on the format of first and last name. It is probably better not to validate the name at all, apart from checking that it is empty.


I have created a custom regex to deal with names:

I have tried these types of names and found working perfect

  1. John Smith
  2. John D'Largy
  3. John Doe-Smith
  4. John Doe Smith
  5. Hector Sausage-Hausen
  6. Mathias d'Arras
  7. Martin Luther King
  8. Ai Wong
  9. Chao Chang
  10. Alzbeta Bara

My RegEx looks like this:

^([a-zA-Z]{2,}\s[a-zA-Z]{1,}'?-?[a-zA-Z]{2,}\s?([a-zA-Z]{1,})?)

MVC4 Model:

[RegularExpression("^([a-zA-Z]{2,}\\s[a-zA-Z]{1,}'?-?[a-zA-Z]{2,}\\s?([a-zA-Z]{1,})?)", ErrorMessage = "Valid Charactors include (A-Z) (a-z) (' space -)") ]

Please note the double \\ for escape characters

For those of you that are new to RegEx I thought I'd include a explanation.

^               // start of line
[a-zA-Z]{2,}    // will except a name with at least two characters
\s              // will look for white space between name and surname
[a-zA-Z]{1,}    // needs at least 1 Character
\'?-?           // possibility of **'** or **-** for double barreled and hyphenated surnames
[a-zA-Z]{2,}    // will except a name with at least two characters
\s?             // possibility of another whitespace
([a-zA-Z]{1,})? // possibility of a second surname

This regex work for me (was using in Angular 8) :

([a-zA-Z',.-]+( [a-zA-Z',.-]+)*){2,30}

enter image description here

It will be invalid if there is:-

  1. Any whitespace start or end of the name
  2. Got symbols e.g. @
  3. Less than 2 or more than 30

Example invalid First Name (whitespace)

enter image description here

Example valid First Name :

enter image description here


Simplest way. Just check almost 2 words.

/^[^\s]+( [^\s]+)+$/

Valid names

  • John Doe
  • pedro alberto ch
  • Ar. Gen
  • Mathias d'Arras
  • Martin Luther King, Jr.

No valid names

  • John
  • ???

The following expression will work on any language supported by UTF-16 and will ensure that there's a minimum of two components to the name (i.e. first + last), but will also allow any number of middle names.

/^(\S+ )+\S+$/u

At the time of this writing it seems none of the other answers meet all of that criteria. Even ^\p{L}{2,}$, which is the closest, falls short because it will also match "invisible" characters, such as U+FEFF (Zero Width No-Break Space).


After going through all of these answers I found a way to build a tiny regex that supports most languages and only allows for word characters. It even supports some special characters like hyphens, spaces and apostrophes. I've tested in python and it supports the characters below:

^[\w'\-,.][^0-9_!¡?÷?¿/\\+=@#$%ˆ&*(){}|~<>;:[\]]{2,}$

Characters supported:

abcdefghijklmnopqrstwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
áéíóúäëïöüÄ'
???
lLoOuUZàáâäãåacceèéêëeiìíîïlnòóôöõøùúûüuu
ÿýzzñçcšžÀÁÂÄÃÅACCEEÈÉÊËÌÍÎÏIL
NÒÓÔÖÕØÙÚÛÜUUŸÝZZÑßÇŒÆCŠŽ.-
ñÑâê?????????????
????????? ?????? ??