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:
- 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.- If match is not null, then return
true
; else returnfalse
.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:
- Let R be this RegExp object.
- [...]
- [...]
- Let lastIndex be the result of calling the [[Get]] internal method of R with argument "
lastIndex
".- Let i be the value of ToInteger(lastIndex).
- Let global be the result of calling the [[Get]] internal method of R with argument "
global
".- If global is
false
, then let i = 0.- [...]
- [...]
- Let e be r's endIndex value.
- If global is
true
,
- Call the [[Put]] internal method of R with arguments "
lastIndex
", e, andtrue
.- [...]
Therefore, to avoid this behavior, you can
Avoid using global flag
g
This way, at step 7,
i
will be0
instead oflastIndex
.Reset
lastIndex
manually after each useThe 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
orsearch
string methodsmatch
resetslastIndex
to 0, andsearch
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
andglobal
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