How does RegExp.exec
works?
When given a string, RegExp.exec
will:
If the pattern is global (has g
flag), then it will use lastIndex
property in the RegExp
instance and search the string for the pattern from the index indicated. This means that RegExp.exec
is not aware of the input string. It will just take the index as starting point and search the string, no matter whether the string is the same as the previous call or not.
If a match is found, it will return an array with the match, and it also update the fields in the RegExp
instance accordingly, as shown in the reference. lastIndex
will be updated with the position to start the next match.
If a match is not found, it will reset the lastIndex
to 0, and return null
as result of calling RegExp.exec
.
If the pattern is not global (g
flag not set), lastIndex
property will be ignored. The match always starts from index 0 regardless of lastIndex
property.
To be extremely clear:
RegExp
instance will store the position to start next match (lastIndex
), the status of the flags (global
, multiline
, ignorecase
) and the text of the pattern (source
).
The return value of RegExp.exec
is an array that stores the result of the match. The array also have input
property which stores the input string and index
property which stores the 0-based index of the match.
The RegExp.$_
property of RegExp
object
RegExp.$_
property and several other similar properties on RegExp
object are deprecated. Just access them via the array returned by RegExp.exec
. $_
is equivalent to the input
property attached in the array returned by RegExp.exec
.
var arr = pattern.exec(inputString);
if (arr !== null) {
// Print to the console the whole input string that has a match
console.log(arr.input);
}
Since those properties are on the RegExp
object, it is very confusing when you work with multiple RegExp
instances - you don't know whether the properties are from the current or previous execution, such as in this case.
From the behavior that you get, it seems that RegExp.$_
is modified when RegExp.exec
found a match, and it will not be modified (previous value stay) when RegExp.exec
fails to match.
Explanation of the behavior
Please read the part above for full picture of how it works.
I added some comment on what happens behind the scene in your original code:
Global flag
var str="I am really puzzled up";
var str1="Being puzzled is first step towards understanding";
// Global pattern
var patt=new RegExp("puzzled","gi");
// From index 0 of str, found match at index 12
// RegExp.$_ is set to current input - str
// patt.lastIndex is set to index 19
patt.exec(str);
alert(RegExp.$_); //I am really puzzled up *[1]
// From index 19 of str1, can't find any match
// Since no match is found, RegExp.$_'s value is not changed
// patt.lastIndex is set to 0
patt.exec(str1);
alert(RegExp.$_); //I am really puzzled up *[2]
// Found index 0 of str1, found match at index 6
// RegExp.$_ is set to current input - str1
// patt.lastIndex is set to 13
patt.exec(str1);
alert(RegExp.$_); //Being puzzled is first step towards understanding *[3]
No global flag
var str="I am really puzzled up";
var str1="Being puzzled is first step towards understanding";
// Not global
var patt=new RegExp("puzzled","i");
// From index 0 of str, found match at index 12
// RegExp.$_ is set to current input - str
patt.exec(str);
alert(RegExp.$_); //I am really puzzled up
// From index 0 of str1, found match at index 6
// RegExp.$_ is set to current input - str1
patt.exec(str1);
alert(RegExp.$_); //Being puzzled is first step towards understanding