0

Setting the global flag to true:

<script>
var str="I am really puzzled up";
var str1="Being puzzled is first step towards understanding";
var patt=new RegExp("puzzled","gi");
patt.exec(str);
alert(RegExp.$_);   //I am really puzzled up *[1]
patt.exec(str1);
alert(RegExp.$_);   //I am really puzzled up *[2]
patt.exec(str1);
alert(RegExp.$_);   //Being puzzled is first step towards understanding *[3]
</script>

Without setting the global flag to true:

<script>
var str="I am really puzzled up";
var str1="Being puzzled is first step towards understanding";
var patt=new RegExp("puzzled","i");
patt.exec(str);
alert(RegExp.$_);   //I am really puzzled up 
patt.exec(str1);
alert(RegExp.$_);   //Being puzzled is first step towards understanding  
</script>

The outputs have been shown by comments

  • [1]-I am satisfied with this output
  • [2]-Now when i have already matched the pattern with some other string constructor property is still showing me first matched string
  • [3]-It is only by again matching the pattern with the string that i get the desired result.

Why would i have to use patt.exec method twice to change the update the result by constructor property?

Ques-It only happens when global flag of pattern is set to true .If global flag is not set the updation of result by constructor property happens the very first time.

Fabio
  • 23,183
  • 12
  • 55
  • 64
chetan mehta
  • 369
  • 1
  • 3
  • 13
  • `RegExp.$_` is deprecated. https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Deprecated_and_obsolete_features?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FDeprecated_Features#RegExp_Properties – nhahtdh May 16 '13 at 06:19
  • Ok but it still shows me the output (not correct one) for global flag set... and shows correct for not global flag. – chetan mehta May 16 '13 at 06:27
  • Sir on that page its written that they will be completely depreceated in future. At present they can be used – chetan mehta May 16 '13 at 06:28
  • 1
    Deprecated means that you are advised to move away from it if you already use it in old code/not use it in new code. – nhahtdh May 16 '13 at 06:58

1 Answers1

3

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
nhahtdh
  • 55,989
  • 15
  • 126
  • 162
  • I dont think there can be any better explanation than this.. Highly appreciable Sir.Well i think you should certainly get more useful answer points for this... – chetan mehta May 16 '13 at 08:06