Sticky flag "y", searching at position

Let’s explore the process of search with the help of the y flag. It helps to implement the search at a particular position in the source string.

For a better understanding of what it is, let’s start from a practical case. One of the most frequent tasks of the regular expressions is “lexical analysis”. For example, HTML includes attributes and tags, JavaScript contains variables, functions, and more.

Lexical analyzers is a unique area with its algorithms and tools. The common task is reading something at a particular position.

Imagine having a string let let elName = "value" and intend to read the variable name from it, which begins at position 4.

The str.match(/\w+/) call will detect only the first word in the line, either all the words with g flag. But you need just a single word at position 4.

To investigate from a particular position the regexp.exec(str) method is used. In case the regexp has no g or y flags, then this method will search for the first match in the string str just as str.match(regexp).

In case there is g flag, it implements the search in the string str, beginning from the position, stored in the regexp.lastIndex property. If a match is detected, it sets regmatch. exp.lastIndex to the index right after the match.

The lastIndex of a regexp is 0 at the moment of its creation. Then a call to regexp.exec(str) returns matches one by one.

Here is an example with the g flag:

let str = 'let elName';
 
let regexp = /\w+/g;
console.log(regexp.lastIndex); // 0 (lastIndex=0)
 
let str1 = regexp.exec(str);
console.log(str1[0]); // let (1st word)
console.log(regexp.lastIndex); // 3 (post match position)
 
let str2 = regexp.exec(str);
console.log(str2[0]); // elName (2nd word)
console.log(regexp.lastIndex); // 10 (post match position)
 
let str3 = regexp.exec(str);
console.log(str3); // null (no more matches)
console.log(regexp.lastIndex); // 0 (resets at the end of the search)

Each match is returned as an array with additional properties and groups.

All the matches can be received in the loop, as follows:

let str = 'let elName';
let regexp = /\w+/g;
let results;
while (results = regexp.exec(str)) {
	console.log(`Found ${results[0]} at position ${results.index}`);
	// Found let at position 0
	// Found elName at position 4
}

So, this is an alternative to the str.matchAll method.

You can set lastIndex for starting the search from a particular position.

In the example below, a word, beginning from the position 4 is being found:

let str = 'let elName = "elValue"';
let regexp = /\w+/g; // without flag "g", property lastIndex is ignored
regexp.lastIndex = 4;
let word = regexp.exec(str);
console.log(word); // elName

Please, take into account that the search begins at lastIndex position, then going further. If there isn’t any word at the lastIndex position, but it’s after it, then it will be detected:

let str = 'let elName = "elValue"';
let regexp = /\w+/g;
regexp.lastIndex = 3;
let word = regexp.exec(str);
console.log(word[0]); //elName
console.log(word.index); // 4

With the g flag, the lastIndex property sets the beginning position of the search.

The y flag urges regexp.exec to search for at the lastIndex position, not after it, not before it.

So, the search with the y flag will look like this:

let str = 'let elName = "elValue"';
let regexp = /\w+/y;
regexp.lastIndex = 3;
console.log(regexp.exec(str)); // null (there's a space at position 3, not a word)
regexp.lastIndex = 4;
console.log(regexp.exec(str)); // elName (word in position 4)

So, the /\w+/y regexp does not correspond at position 3.

As a conclusion, we can state that the y flag is a useful means for doing a search, and can be considered as a key to a good implementation.




Do you find this helpful?

Related articles