What is the purpose of the "y" sticky pattern in JavaScript RegExps?

MDN introduced the "y" flag for JavaScript RegExp. Here is an excerpt from the documentation :

at

sticky; matches only the index specified by the lastIndex property of this regex in the target string (and does not attempt to match against later indices)

There is 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 in this case, there is no difference between using the global g flag :

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'

      

The same conclusion. So I think there might be something else regarding the "y" flag, and it seems that the MDN example is not a real use case for this modifier as it seems to just work as a replacement for the global "g" modifier here.

So what could be the real use case for this experimental "y" sticky flag? What is its purpose in "matching only the RegExp.lastIndex property" and how does it differ from "g" when used with RegExp.prototype.exec

?

Thanks for your attention.

+5


source to share


2 answers


The difference between y

and g

is described in practical modern JavaScript :

The flag lastIndex

advances lastIndex

as g

but only if a match is found starting at lastIndex

, no forward search
. To improve the performance of writing lexical analyzers using JavaScript , a checkbox has been added ...

As for the real use case,

This can be used to query a regexp to match starting at position n

where n

is what is set tolastIndex

. In the case of a non-multiline regular expression, the value lastIndex

equal 0

to the anchor flag will actually be the same as the start of the regular expression using, ^

which requires the start of the match at the beginning of the search text.



And here is an example from this blog where a property is lastIndex

manipulated before calling the method test

, thus causing different matching 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

      

+7


source


There is a definite difference in behavior as shown 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 still haven't figured out what's going on there.

+2


source







All Articles