Malakai
Malakai

Reputation: 3131

Unique regex for first name and last name

I have a single input where users should enter name and surname. The problem is i need to use checking regEx. There's a list of a requirements:

  1. The name should start from Capital Letter (not space)
  2. There can't be space stacks
  3. It's obligate to support these Name and Surname (all people are able to write theirs first/name). Example:

    John Smith
    and
    Armirat Bair Hossan 
    
  4. And the last symbol shouldn't be space.

Please help,

ATM i have regex like

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

but it denies ALL input, which is not good

Thanks for helping me

UPDATE:

CORRECT INPUT: 
"John Smith"
"Alberto del Muerto"

INCORRECT
"   John Smith   "
" John Smith"

Upvotes: 2

Views: 1509

Answers (4)

ProPhoto
ProPhoto

Reputation: 31

Try this one

^[^- '.](?=(?![A-Z]?[A-Z]))(?=(?![a-z]+[A-Z]))(?=(?!.*[A-Z][A-Z]))(?=(?!.*[- '][- '.]))(?=(?!.*[.][-'.]))[A-Za-z- '.]{1,}$

There is also an interactive Demo of this pattern available at an external website.

Edited: New one supporting most of European languages:

^(?=([A-ZÀ-ÝŐŰẞŒ]|([a-zß-ÿőűœ][ '])))(?=(?![a-zß-ÿőűœ]+[A-ZÀ-ÝŐŰẞŒ]))(?=(?!.*[A-ZÀ-ÝŐŰẞŒ][A-ZÀ-ÝŐŰẞŒ]))(?=(?!.*[- '][- ']))[A-ZÀ-ÝŐŰẞŒß-ÿőűœa-z- ']{2,}([a-zß-ÿőűœ]|(, Jr.))$
Name Result
yyTyue Tgshh fail: starts with a small letter
CxCx5C5C fail: numbers
STEVE SMITH fail: all capital ...
Stev3 Smith fail: 3 at the end of the name
STeve Smith fail: ST
Steve SMith fail: SM
Steve Sm1th fail: 1 instead of i
John Smith fail: extra space)
'John Smith fail: ' at the beginning
John Smith- fail: - at the end
d'Are to Beaware passed 100%
Jo Blow passed 100%
Hyoung Kyoung Wu passed 100%
Mike O'Neal passed 100%
Steve Johnson-Smith passed 100%
Jozef-Schmozev Hiemdel passed 100%
O Henry Smith passed 100%
Mathais d'Arras passed 100%
Martin Luther King Jr passed 100%
Downtown-James Brown passed 100%
Darren McCarty passed 100%
An Ni passed 100%
George De FunkMaster passed 100%
Kurtis B-Ball Basketball passed 100%
Ahmad el Jeffe passed 100%
André Désirée Jördis passed 100%
René Jürg passed 100%
Esmé Adélaïde passed 100%
Adorján Ágnes passed 100%
Bendegúz Bertók passed 100%
Ávg É Ñu passed 100%
Ógl Ú Üd passed 100%
Aarón Abrahán Aída passed 100%
Íñigo Jerónima passed 100%

function myFunction() {
    
  const pattern = "^(?=([A-ZÀ-ÝŐŰẞŒ]|([a-zß-ÿőűœ][ '])))(?=(?![a-zß-ÿőűœ]+[A-ZÀ-ÝŐŰẞŒ]))(?=(?!.*[A-ZÀ-ÝŐŰẞŒ][A-ZÀ-ÝŐŰẞŒ]))(?=(?!.*[- '][- ']))[A-ZÀ-ÝŐŰẞŒß-ÿőűœa-z- ']{2,}([a-zß-ÿőűœ]|(, Jr.))$";
    var regex = new RegExp(pattern, 'gm');
    var a = document.getElementById("myText");
  var b = a.value;
  var c = regex.test(b);
  var d = document.getElementById("result") ;
  d.innerHTML = "Result:";
  if(b != ""){
      if(c){
          d.innerHTML += " passed";
      }
      else{
        d.innerHTML += " failed";
        }
  }
  else{
    return
  }
}
input[type=text] {
  width: 99%;
  padding: 4px;
  margin: 8px 0;
  display: inline-block;
  border: 1px solid #ccc;
  box-sizing: border-box;
}
button {
  background-color: #04AA6D;
  color: white;
  padding: 4px;
  border: none;
  cursor: pointer;
  width: 25%;
}

button:hover {
  opacity: 0.8;
}
<h2>Name Validation Regex Pattern </h2>
<div class="container">
      <label for="name"><b>Name</b></label>
        <input type="text" id="myText"  placeholder="Enter Your Name" name="name" value="">
</div>
 <div class="container">

<button onclick="myFunction()">Try it</button>
<p id="result"> Result: </p>
</div>
</div>

Upvotes: 2

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626754

You can use

^[\p{Lu}\p{M}][\p{L}\p{M},.'-]+(?: [\p{L}\p{M},.'-]+)*$

or

^\p{Lu}\p{M}*+(?:\p{L}\p{M}*+|[,.'-])++(?: (?:\p{L}\p{M}*+|[,.'-])++)*+$

See the regex demo and demo 2

Java declaration:

if (str.matches("[\\p{Lu}\\p{M}][\\p{L}\\p{M},.'-]+(?: [\\p{L}\\p{M},.'-]+)*")) { ... } 
// or if (str.matches("\\p{Lu}\\p{M}*+(?:\\p{L}\\p{M}*+|[,.'-])++(?: (?:\\p{L}\\p{M}*+|[,.'-])++)*+")) { ... } 

The first regex breakdown:

  • ^ - start of string (not necessary with matches() method)
  • [\p{Lu}\p{M}] - 1 Unicode letter (incl. precomposed ones as \p{M} matches diacritics and \p{Lu} matches any uppercase Unicode base letter)
  • [\p{L}\p{M},.'-]+ - matches 1 or more Unicode letters, a ,, ., ' or - (if 1 letter names are valid, replace + with - at the end here)
  • (?: [\p{L}\p{M},.'-]+)* - 0 or more sequences of
    • - a space
    • [\p{L}\p{M},.'-]+ - 1 or more characters that are either Unicode letters or commas, or periods, or apostrophes or -.
  • $ - end of string (not necessary with matches() method)

NOTE: Sometimes, names contain curly apostrophes, you can add them to the character classes ([‘’]).

The 2nd regex is less effecient but is more accurate as it will only match diacritics after base letters. See more about matching Unicode letters at regular-expressions.info:

To match a letter including any diacritics, use \p{L}\p{M}*+.

Upvotes: 4

Joop Eggen
Joop Eggen

Reputation: 109547

You made a typo: the second \\ should be in front of p. However even then there is a check missing for a trailing space

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

For a .matches the following would suffice

"\\p{L}[\\p{L} ,.'-]*[\\p{L}.]"

Names like "del Rey, Hidalgo" do not require an initial capital.

Also I would advise to simply .trim() the input; imagine a user regarding at the input being rejected for a spurious blank.

Upvotes: 1

VDanyliuk
VDanyliuk

Reputation: 1049

Try this

^[A-Z][a-z]+(([\s][A-Z])?[a-z]+){1,2}$

but use \\ instead \ for java

Upvotes: 0

Related Questions