6

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

5
  • Should your app accept George Henry as a name? If so, you have to allow spaces. And what about Gérard Depardieu? Or محمد (Mohammed)? Commented Feb 11, 2017 at 9:47
  • @RolandIllig Thanks for the thought but i asked a question about this days ago and didn't get any answers (stackoverflow.com/questions/42074834/…), it doesn't seem possible, so i thought i keep it simple and O'Reilly and محمد have to write OReily and Mohammed unfortunately, if you have a solution or a guide to this please let me know Commented Feb 11, 2017 at 9:55
  • and of course i still have the issue of spaces, some write Marry Anne others write Marry-Anne Commented Feb 11, 2017 at 10:02
  • 1
    See my answer. It is much simpler than the answer you accepted and shows how to extend the solution. You do not really need any lookaheads here. Commented Feb 11, 2017 at 10:03
  • I answered your question Commented Feb 11, 2017 at 12:10

4 Answers 4

4

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]+)*$/;
Sign up to request clarification or add additional context in comments.

2 Comments

That's what I was going to write. But you can avoid escaping dash (-) if it is at the end of the set (not mandatory, though).
it is still accepting a dash at the end, i know i didn't mention that in my question but please guide on how to do that
1

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).

Comments

1

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

1 Comment

Hmm.. this regex silently passes something like sdfs----safasf, while Pranav C Balan's answer works perfectly.
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.