What is the "y" flag in regular expressions? What is its function?

Asked

Viewed 94 times

3

Some time ago I discovered that regular expressions can also use the flag y, call for Sticky.

I did not understand very well its function. What is its purpose? Is there any relation with another flag?

  • 1

    I added a few more things to the answer (about the relationship with others flags)

1 answer

3


It is used to indicate that the search must start from the position indicated by lastIndex, and it only gives match if found exactly at that position (different from a regex non-sticky, which checks at any position of 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 regex Sticky fails because lastIndex starts with zero value.

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

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

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

But attention, if regex uses bookmark ^ (string start), a flag y can be a problem:

// verifica se a string começa com uma letra minúscula
let r = /^[a-z]/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


Relationship with others flags

If it’s the flag case insensitive (i), 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 flags s and u there is also no problem (the first changes the behavior of the point, which now also considers line breaks, and the second enables the Unicode mode - nothing that interferes with the functioning Sticky in itself).

If you use the flag m (which causes the markers ^ and $ also means 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 = /^[a-z]/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

I already use it with the flag g can cause some confusion (tests below made 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 did not find all occurrences, only the first two (the documentation says that in this case the flag g is ignored, but the result is strange, because if it were really this, it should be the same as the second test, ie, ['c']).

Using only y, is the normal behavior that we have seen above, only looks for an occurrence in the index indicated.

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 one should avoid using the flags y and g together. And it makes sense, because one only searches from an exact position, and another searches all the occurrences of the string (i.e., they are contradictory objectives that cannot coexist).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.