MDN introduced the 'y' sticky flag for JavaScript RegExp. Here is a documentation excerpt:
y
sticky; matches only from the index indicated by the lastIndex property of this regular expression in the target string (and does not attempt to match from any later indexes).
There's also an example:
var text = 'First line\nSecond line';
var regex = /(\S+) line\n?/y;
var match = regex.exec(text);
console.log(match[1]); // prints 'First'
console.log(regex.lastIndex); // prints '11'
var match2 = regex.exec(text);
console.log(match2[1]); // prints 'Second'
console.log(regex.lastIndex); // prints '22'
var match3 = regex.exec(text);
console.log(match3 === null); // prints 'true'
But there isn't actually any difference between the usage of the g global flag in this case:
var text = 'First line\nSecond line';
var regex = /(\S+) line\n?/g;
var match = regex.exec(text);
console.log(match[1]); // prints 'First'
console.log(regex.lastIndex); // prints '11'
var match2 = regex.exec(text);
console.log(match2[1]); // prints 'Second'
console.log(regex.lastIndex); // prints '22'
var match3 = regex.exec(text);
console.log(match3 === null); // prints 'true'
Same output. So I guess there might be something else regarding the 'y' flag and it seems that MDN's example isn't a real use-case for this modifier, as it seems to just work as a replacement for the 'g' global modifier here.
So, what could be a real use-case for this experimental 'y' sticky flag? What's its purpose in "matching only from the RegExp.lastIndex property" and what makes it differ from 'g' when used with RegExp.prototype.exec
?
Thanks for the attention.
The difference between y
and g
is described in Practical Modern JavaScript:
The sticky flag advances
lastIndex
likeg
but only if a match is found starting atlastIndex
, there is no forward search. The sticky flag was added to improve the performance of writing lexical analyzers using JavaScript...
As for a real use case,
It could be used to require a regular expression match starting at position
n
wheren
is whatlastIndex
is set to. In the case of a non-multiline regular expression, alastIndex
value of0
with the sticky flag would be in effect the same as starting the regular expression with^
which requires the match to start at the beginning of the text searched.
And here is an example from that blog, where the lastIndex
property is manipulated before the test
method invocation, thus forcing different match results:
var searchStrings, stickyRegexp;
stickyRegexp = /foo/y;
searchStrings = [
"foo",
" foo",
" foo",
];
searchStrings.forEach(function(text, index) {
stickyRegexp.lastIndex = 1;
console.log("found a match at", index, ":", stickyRegexp.test(text));
});
Result:
"found a match at" 0 ":" false
"found a match at" 1 ":" true
"found a match at" 2 ":" false
There is definitely a difference in behaviour as showed below:
var text = "abc def ghi jkl"
undefined
var regexy = /\S(\S)\S/y;
undefined
var regexg = /\S(\S)\S/g;
undefined
regexg.exec(text)
Array [ "abc", "b" ]
regexg.lastIndex
3
regexg.exec(text)
Array [ "def", "e" ]
regexg.lastIndex
7
regexg.exec(text)
Array [ "ghi", "h" ]
regexg.lastIndex
11
regexg.exec(text)
Array [ "jkl", "k" ]
regexg.lastIndex
15
regexg.exec(text)
null
regexg.lastIndex
0
regexy.exec(text)
Array [ "abc", "b" ]
regexy.lastIndex
3
regexy.exec(text)
null
regexy.lastIndex
0
..but I have yet to fully understand what is going on there.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With