问题
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
gflag), then it will uselastIndexproperty in theRegExpinstance and search the string for the pattern from the index indicated. This means thatRegExp.execis 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
RegExpinstance accordingly, as shown in the reference.lastIndexwill be updated with the position to start the next match.If a match is not found, it will reset the
lastIndexto 0, and returnnullas result of callingRegExp.exec.If the pattern is not global (
gflag not set),lastIndexproperty will be ignored. The match always starts from index 0 regardless oflastIndexproperty.
To be extremely clear:
RegExpinstance 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.execis an array that stores the result of the match. The array also haveinputproperty which stores the input string andindexproperty 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