0

I'm familiar with Java regex but not Javascript regex.

I want to check the validity of the string input if it looks like a first name. A first name can either be xxxx xxx or xxx where x is a letter. Note that in what I've said, the number of x's vary. So here's my code:

function checkName(name) {
     var pattern = new RegExp('([A-Za-z]+|[A-Za-z]+\\s[A-Za-z]+)');
     return pattern.test(name);
}

I've made a function that will process the name from the text input in my form. Now it is working for inputs such as Michael or Michael James. However, it also works on M3 for example which has a number and is supposed to be not working. So any help on this one experts out there in the world?

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
Jude Maranga
  • 865
  • 2
  • 9
  • 27
  • 3
    Maybe you just want to ensure a whole string matches the pattern? Add `^` at the start and `$` at the end. Try `var pattern = /^([A-Za-z]+|[A-Za-z]+\s[A-Za-z]+)$/;` – Wiktor Stribiżew Aug 30 '16 at 13:09
  • @WiktorStribiżew yes that's what I want! Hahaha thank you sir. I don't know that yet but now I know. I'm familiar with Java regex but not Javascript regex. Thank you again! :) – Jude Maranga Aug 30 '16 at 13:11
  • 1
    @JudeMaranga Also, I think the below expression is more optimal: `^[A-Za-z]+(\\s[A-Za-z]+)?$` – Vasan Aug 30 '16 at 13:14

1 Answers1

3

There is no matches method in JavaScript (unlike Java). If you just want to ensure a whole string matches the pattern, add ^ at the start and $ at the end. Also, it is advised to use a regex literal notation /.../ if your regex pattern is static.

Use

var pattern = /^([A-Za-z]+|[A-Za-z]+\s[A-Za-z]+)$/;
              ^^                                ^  

To further optimize it (although the performance gain will be tiny), you may use an optional group (?:....)? (see vasan's comment):

var pattern = /^[A-Za-z]+(?:\s[A-Za-z]+)?$/;
                         ^^^^^^^^^^^^^^^^ 

See the regex demo.

function checkName(name) {
     var pattern = /^([A-Za-z]+|[A-Za-z]+\s[A-Za-z]+)$/;
     return pattern.test(name);
}

let log  = document.querySelector("#log"),
    test = document.querySelector("#test");

test.addEventListener("input", e => {
  if(checkName(test.value)){
    log.style.color = "green";
    log.innerHTML = "Passed!";
  }else{
    log.style.color = "red";
    log.innerHTML = "Failed";
  }
});
#test:focus{outline: none;}
<input type="text" id="test" autofocus /><br />
<span id="log"></span>
Community
  • 1
  • 1
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • And you're usually so good at marking duplicates... –  Aug 30 '16 at 13:19
  • What's the : for? – Jude Maranga Aug 30 '16 at 13:23
  • @torazaburo: I answered because OP comes from Java, actually. The fact that the Java `String#matches()` is not present in JavaScript made me post an answer. – Wiktor Stribiżew Aug 30 '16 at 13:24
  • @JudeMaranga: The `(?:...)` is a non-capturing group that only groups subpatterns without storing a captured value in the group buffer. The `?` is a quantifier matching 1 or 0 occurrences of the quantified subpattern. – Wiktor Stribiżew Aug 30 '16 at 13:24
  • @WiktorStribiżew Okaay thanks! Btw, one last question (though this is not really directly related to the post). This rule, the one adding ^ at the beginning and $ in the end, is this true to PHP regex too, if in any case you know? – Jude Maranga Aug 30 '16 at 13:29
  • In PHP, for validation reasons, I'd use `\A` instead of `^` and `\z` instead of `$`. In PHP, you need the anchors, as there is no Java-like `String#matches` either – Wiktor Stribiżew Aug 30 '16 at 13:30
  • @WiktorStribiżew But that basically means the same? Or are they even necessary in PHP regex to achieve the same goal as I have in my problem? – Jude Maranga Aug 30 '16 at 13:31
  • 1
    `$` in PHP may match before the final newline, use `\z` instead. They are necessary to anchor the match at the start/end position. – Wiktor Stribiżew Aug 30 '16 at 13:32