Joe D
Joe D

Reputation: 75

Javascript validation regex for names

I am looking to accept names in my app with letters and hyphens or dashes, i based my code on an answer i found here and coded that:

function validName(n){
  var nameRegex = /^[a-zA-Z\-]+$/;
  if(n.match(nameRegex) == null){
    return "Wrong";
  }
  else{
    return "Right";
  }
}

the only problem is that it accepts hyphen as the first letter (even multiple ones) which i don't want. thanks

Upvotes: 6

Views: 9372

Answers (4)

Blair Nangle
Blair Nangle

Reputation: 1541

The below regex is useful for surnames if one wants to forbid leading or trailing non-alphabetic characters, while permitting a small set of common word-joining characters in between two names.

^[a-zA-Z]+[- ']{0,1}[a-zA-Z]+$

Explanation

  • ^[a-zA-Z]+ must begin with at least one letter
  • [- ']{0,1} allow zero or at most one of any of -, or '
  • [a-zA-Z]+$ must end with at least one letter

Test cases

(The double-quotes have been added purely to illustrate the presence of whitespace.)

"Blair"         => match
" Blair"        => no match
"Blair "        => no match
"-Blair"        => no match
"- Blair"       => no match
"Blair-"        => no match
"Blair -"       => no match
"Blair-Nangle"  => match
"Blair--Nangle" => no match
"Blair Nangle"  => match
"Blair -Nangle" => no match
"O'Nangle"      => match
"BN"            => match
"BN "           => no match
" O'Nangle"     => no match
"B"             => no match
"3Blair"        => no match
"!Blair"        => no match
"van Nangle"    => match
"Blair'"        => no match
"'Blair"        => no match

Limitations include:

  • No single-character surnames
  • No surnames composed of more than two words

Check it out on regex101.

Upvotes: 1

Pranav C Balan
Pranav C Balan

Reputation: 115202

Use negative lookahead assertion to avoid matching the string starting with a hyphen. Although there is no need to escape - in the character class when provided at the end of character class. Use - removed character class for avoiding - at ending or use lookahead assertion.

var nameRegex = /^(?!-)[a-zA-Z-]*[a-zA-Z]$/;
// or
var nameRegex = /^(?!-)(?!.*-$)[a-zA-Z-]+$/;

var nameRegex = /^(?!-)[a-zA-Z-]*[a-zA-Z]$/;
// or
var nameRegex1 = /^(?!-)(?!.*-$)[a-zA-Z-]+$/;

function validName(n) {
  if (n.match(nameRegex) == null) {
    return "Wrong";
  } else {
    return "Right";
  }
}

function validName1(n) {
  if (n.match(nameRegex1) == null) {
    return "Wrong";
  } else {
    return "Right";
  }
}

console.log(validName('abc'));
console.log(validName('abc-'));
console.log(validName('-abc'));
console.log(validName('-abc-'));
console.log(validName('a-b-c'));

console.log(validName1('abc'));
console.log(validName1('abc-'));
console.log(validName1('-abc'));
console.log(validName1('-abc-'));
console.log(validName1('a-b-c'));

FYI : You can use RegExp#test method for searching regex match and which returns boolean based on regex match.

if(nameRegex.test(n)){
  return "Right";
}
else{
  return "Wrong";
}


UPDATE : If you want only single optional - in between words, then use a 0 or more repetitive group which starts with -as in @WiktorStribiżew answer .

var nameRegex = /^[a-zA-Z]+(?:-[a-zA-Z]+)*$/;

Upvotes: 4

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626689

You need to decompose your single character class into 2 , moving the hyphen outside of it and use a grouping construct to match sequences of the hyphen + the alphanumerics:

var nameRegex = /^[a-zA-Z]+(?:-[a-zA-Z]+)*$/;

See the regex demo

This will match alphanumeric chars (1 or more) at the start of the string and then will match 0 or more occurrences of - + one or more alphanumeric chars up to the end of the string.

If there can be only 1 hyphen in the string, replace * at the end with ? (see the regex demo).

If you also want to allow whitespace between the alphanumeric chars, replace the - with [\s-] (demo).

Upvotes: 1

ssc-hrep3
ssc-hrep3

Reputation: 16069

You can either use a negative lookahead like Pranav C Balan propsed or just use this simple expression:

^[a-zA-Z]+[a-zA-Z-]*$

Live example: https://regex101.com/r/Dj0eTH/1

Upvotes: 1

Related Questions