javascript – What is the "y" flag in regular expressions? What is your role?

Question:

Some time ago I discovered that regular expressions can also use the y flag , called a sticky .

I didn't quite understand its function. What is your purpose? Is there any relationship with another flag ?

Answer:

It is used to indicate that the search should start from the position indicated by lastIndex , and it only matches if it is found at exactly that position (unlike a non-sticky regex, which checks anywhere in the string):

// expressões para buscar uma letra minúscula
let notSticky = /[a-z]/;
let sticky = /[a-z]/y;

let s = '123abc';
console.log(notSticky.test(s)); // true

console.log(sticky.test(s)); // false
sticky.lastIndex = 3;
console.log(sticky.test(s)); // true

sticky.lastIndex = 1;
console.log(sticky.test(s)); // false

The first attempt with the sticky regex fails because lastIndex starts with the value zero.

You can check if the regex has this flag using the sticky property :

let notSticky = /[a-z]/;
let sticky = /[a-z]/y;

console.log(notSticky.sticky); // false
console.log(sticky.sticky); // true

But beware , if the regex uses the ^ tag (beginning of the string), the y flag can give a problem:

 // verifica se a string começa com uma letra minúscula let r = /^[az]/y; let s = '12abc'; console.log(r.test(s)); // false r.lastIndex = 2; console.log(r.test(s)); // false, a posição 2 não é o início da string r.lastIndex = 2; console.log(r.test('abc')); // false, a posição 2 não é o início da string r.lastIndex = 0; console.log(r.test('abc')); // true, a posição 0 é o início da string

Relation to other flags

If it is the case insensitive flag ( i ), there is no interference:

// com a flag "i", para procurar maiúsculas e minúsculas
let r = /[a-z]/yi;

let s = '123ABC';

console.log(r.test(s)); // false
r.lastIndex = 3;
console.log(r.test(s)); // true

With the s and u flags there is no problem either (the first changes the dot's behavior, which also considers line breaks, and the second enables Unicode mode – nothing that interferes with the sticky operation itself).

If you use the m flag (which makes the ^ and $ markers also signify the beginning and end of a line):

 // verifica tem uma letra minúscula no início da string ou início de linha let r = /^[az]/ym; let s = '12abc'; console.log(r.test(s)); // false r.lastIndex = 2; console.log(r.test(s)); // false, a posição 2 não é o início da string r.lastIndex = 2; console.log(r.test('abc')); // false, a posição 2 não é o início da string r.lastIndex = 0; console.log(r.test('abc')); // true, a posição 0 é o início da string r.lastIndex = 2; console.log(r.test('1\nabc')); // true, a posição 2 é o início de linha

Already the use with the g flag can cause some confusion (tests done below in Chrome):

let s = 'ab12cd34xy56';

let r = /[a-z]/yg;
r.lastIndex = 4;
console.log(s.match(r)); // ["a", "b"]

r = /[a-z]/y;
r.lastIndex = 4;
console.log(s.match(r)); // ["c"]

r = /[a-z]/g;
r.lastIndex = 4;
console.log(s.match(r)); // ["a", "b", "c", "d", "x", "y"]

With both flags , the lastIndex was ignored and the search started at the beginning of the string. But it didn't find all the occurrences, just the first two (the documentation says that in this case the g flag is ignored, but the result is strange, because if that were really it, it should be the same as the second test, ie ['c'] ).

Using only y , the normal behavior we've already seen above, is to find only one occurrence in the indicated index.

And using only g , it finds all occurrences, always starting from the beginning of the string, regardless of what was set in lastIndex before.

My conclusion is that you should avoid using the y and g flags together. And it makes sense, as one only searches from an exact position, and the other searches all occurrences of the string (that is, they are contradictory goals that cannot coexist).

Scroll to Top