Unexpected Javascript RegExp behavior [duplicate] Unexpected Javascript RegExp behavior [duplicate] google-chrome google-chrome

Unexpected Javascript RegExp behavior [duplicate]


Per documentation: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/test#Description

test called multiple times on the same global regular expression instance will advance past the previous match.

You can confirm this behavior:

var test = new RegExp( '[0-9]', 'g' );test.test('01'); //truetest.test('01'); //truetest.test('01'); //false

It doesn't make sense to use the g flag if all you want is to confirm a single match against various strings.


Remove the 'g' flag. When you use the 'g' flag, it updates the lastIndex property of the regex (preparing for a successive search on the same string) and then starts the next search from that index value (thus giving you a false reading on your next search).

Similar question and answer here: Why is Regex Javascript //g flag affecting state?


According to MDN,

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.

Technically, the ECMAScript 5.1 spec says

15.10.6.3 RegExp.prototype.test(string)

The following steps are taken:

  1. Let match be the result of evaluating the RegExp.prototype.exec (15.10.6.2) algorithm upon this RegExp object using string as the argument.
  2. If match is not null, then return true; else return false.

15.10.6.2 RegExp.prototype.exec(string)

Performs a regular expression match of string against the regular expression and returns an Array object containing the results of the match, or null if string did not match.

The String ToString(string) is searched for an occurrence of the regular expression pattern as follows:

  1. Let R be this RegExp object.
  2. [...]
  3. [...]
  4. Let lastIndex be the result of calling the [[Get]] internal method of R with argument "lastIndex".
  5. Let i be the value of ToInteger(lastIndex).
  6. Let global be the result of calling the [[Get]] internal method of R with argument "global".
  7. If global is false, then let i = 0.
  8. [...]
  9. [...]
  10. Let e be r's endIndex value.
  11. If global is true,
    1. Call the [[Put]] internal method of R with arguments "lastIndex", e, and true.
  12. [...]

Therefore, to avoid this behavior, you can

  • Avoid using global flag g

    This way, at step 7, i will be 0 instead of lastIndex.

  • Reset lastIndex manually after each use

    The value of the lastIndex property specifies the String position at which to start the next match.

    For example,

    var test = /[0-9]/g;test.test('0');      // truetest.lastIndex;      // 1test.lastIndex = 0;test.test('1');      // true
  • Use match or search string methods

    match resets lastIndex to 0, and search ignores it:

    15.5.4.10 String.prototype.match (regexp)

    [...] [If] global is true, call the [[Put]] internal method of rx with arguments "lastIndex" and 0. [...]

    15.5.4.12 String.prototype.search (regexp)

    [...] Search the value string from its beginning for an occurrence of the regular expression pattern rx. [...] The lastIndex and global properties of regexp are ignored when performing the search. [...]

    For example,

    var test = /[0-9]/g;test.test('0');        // truetest.lastIndex;        // 1'0'.search(test) > -1; // truetest.lastIndex;        // 1 (unaltered)!!'0'.match(test);     // truetest.lastIndex;        // 0