RegExp constructor properties input

情到浓时终转凉″ 提交于 2019-12-13 03:03:50

问题


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.


回答1:


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


来源:https://stackoverflow.com/questions/16579947/regexp-constructor-properties-input

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!