4

I've been trying evaluate a string based in a regular expression, however I noticed a weird behaviour and when I test with the regular expression more than once. The test method alternates between true and false . Check this codepen --> http://codepen.io/gpincheiraa/pen/BoXrEz?editors=001

var emailRegex = /^([a-zA-Z0-9_\.\-]){0,100}\@(([a-zA-Z0-9\-]){0,100}\.)+([a-zA-Z0-9]{2,4})+$/,
  phoneChileanRegex = /^\+56\S*\s*9\S*\s*\d{8}(?!\@\w+)/g,
   number = "+56982249953";

if(!number.match(phoneChileanRegex)  && !number.match(emailRegex) ) {
  console.log("it's not a phone number or email address");
}

//Weird Behaviour
console.log(phoneChileanRegex.test(number)); --> true
console.log(phoneChileanRegex.test(number)); --> false
  • 2
    That is happening because of `g` flag, Check [CodePen](http://codepen.io/anon/pen/NxKbye?editors=001) – Tushar Dec 02 '15 at 04:13

2 Answers2

11

From the MDN documentation:

As with exec() (or in combination with it), test() called multiple times on the same global regular expression instance will advance past the previous match.

So, the second time you call the method, it will look for a match after the first match, i.e. after +56982249953. There is no match because the pattern is anchored to the start of the string (^) (and because there are no characters left), so it returns false.

To make this work you have to remove the g modifier.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
6

That's because the test method, like many RegExp methods, tries to find multiple matches in the same string when used with the g flag. To do this, it keeps track of position it should search from in the RegExp's lastIndex property. If you don't need to find multiple matches, just don't put the g flag. And if you ever want to use it, just remember to set regex.lastIndex to 0 when you want to test a new string.

Read more about lastIndex on MDN

Domino
  • 6,314
  • 1
  • 32
  • 58
  • Exactly apt answer. I found out by placing a breakpoint after 1st console.log and inspecting `phoneChileanRegex.lastIndex` and it showed 12, which means it was tracking the position due to `g` flag – NiRUS Dec 02 '15 at 04:30
  • Thanks! I finally understand what's happened when i use the `.test` method. Generally I use the `g` flag when I use the `String.replace` method and I dont knew about this behaviour in the `Regexp.test` method. – Gonzalo Pincheira Arancibia Dec 02 '15 at 18:58