تسÙ
Ø Ø§ÙØ¹ÙاÙ
Ø© y Ø¨Ø§ÙØ¨ØØ« Ù٠اÙÙ
ÙØ¶Ø¹ اÙÙ
ØØ¯Ø¯ ÙÙ Ø§ÙØ³ÙØ³ÙØ© اÙÙ
صدر.
To grasp the use case of y flag, and better understand the ways of regexps, letâs explore a practical example.
One of common tasks for regexps is âlexical analysisâ: we get a text, e.g. in a programming language, and need to find its structural elements. For instance, HTML has tags and attributes, JavaScript code has functions, variables, and so on.
تعد ÙØªØ§Ø¨Ø© اÙÙ ØÙÙØ§Øª اÙÙ Ø¹Ø¬Ù ÙØ© ٠جاÙÙØ§ Ø®Ø§ØµÙØ§ Ø Ù Ø¹ Ø£Ø¯ÙØ§ØªÙ ÙØ®ÙØ§Ø±Ø²Ù ÙØ§ØªÙ Ø§ÙØ®Ø§ØµØ© Ø ÙØ°ÙÙ ÙØ§ ÙØªØ¹Ù Ù Ù٠ذÙÙ Ø ÙÙÙÙ ÙÙØ§Ù Ù ÙÙ Ø© Ù Ø´ØªØ±ÙØ©: ÙØ±Ø§Ø¡Ø© Ø´ÙØ¡ ٠ا Ù٠اÙÙ ÙØ¶Ø¹ اÙÙ ØØ¯Ø¯.
عÙ٠سبÙ٠اÙÙ
Ø«Ø§Ù ÙØ¯ÙÙØ§ Ø³ÙØ³ÙØ© Ø§ÙØªØ¹ÙÙÙ
ات Ø§ÙØ¨Ø±Ù
Ø¬ÙØ© let varName =" value " Ø ÙÙØØªØ§Ø¬ Ø¥ÙÙ ÙØ±Ø§Ø¡Ø© اسÙ
اÙÙ
ØªØºÙØ± Ù
ÙÙ Ø Ø§ÙØ°Ù ÙØ¨Ø¯Ø£ Ù٠اÙÙ
ÙØ¶Ø¹ 4.
Ø³ÙØ¨ØØ« ع٠اسÙ
Ù
ØªØºÙØ± باستخداÙ
ÙÙ
Ø· regexp : \ w +. Ù٠اÙÙØ§Ùع Ø ØªØØªØ§Ø¬ أسÙ
اء Ù
ØªØºÙØ±Ø§Øª Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت Ø¥ÙÙ regexp Ø£ÙØ«Ø± تعÙÙØ¯Ùا ÙÙÙÙØ§Ù ÙÙ
Ø·Ø§Ø¨ÙØ© دÙÙÙØ© Ø ÙÙÙÙ ÙÙØ§ ÙØ§ ÙÙÙ
.
- A call to
str.match(/\w+/)will find only the first word in the line (let). Thatâs not it. - We can add the flag
g. But then the callstr.match(/\w+/g)will look for all words in the text, while we need one word at position4. Again, not what we need.
So, how to search for a regexp exactly at the given position?
Letâs try using method regexp.exec(str).
For a regexp without flags g and y, this method looks only for the first match, it works exactly like str.match(regexp).
â¦But if thereâs flag g, then it performs the search in str, starting from position stored in the regexp.lastIndex property. And, if it finds a match, then sets regexp.lastIndex to the index immediately after the match.
In other words, regexp.lastIndex serves as a starting point for the search, that each regexp.exec(str) call resets to the new value (âafter the last matchâ). Thatâs only if thereâs g flag, of course.
ÙØ°ÙÙ Ø Ø§ÙÙ
ÙØ§ÙÙ
ات اÙÙ
تتاÙÙØ© ÙØ¹Ùدة regexp.exec (str) ØªØªØ·Ø§Ø¨Ù ÙØ§ØØ¯Ø© تÙÙ Ø§ÙØ£Ø®Ø±Ù.
Hereâs an example of such calls:
let str = 'let varName'; // Let's find all words in this string
let regexp = /\w+/g;
alert(regexp.lastIndex); // 0 (initially lastIndex=0)
let word1 = regexp.exec(str);
alert(word1[0]); // let (1st word)
alert(regexp.lastIndex); // 3 (position after the match)
let word2 = regexp.exec(str);
alert(word2[0]); // varName (2nd word)
alert(regexp.lastIndex); // 11 (position after the match)
let word3 = regexp.exec(str);
alert(word3); // null (no more matches)
alert(regexp.lastIndex); // 0 (resets at search end)
We can get all matches in the loop:
let str = 'let varName';
let regexp = /\w+/g;
let result;
while (result = regexp.exec(str)) {
alert( `Found ${result[0]} at position ${result.index}` );
// Found let at position 0, then
// Found varName at position 4
}
Such use of regexp.exec is an alternative to method str.matchAll, with a bit more control over the process.
Letâs go back to our task.
We can manually set lastIndex to 4, to start the search from the given position!
Like this:
let str = 'let varName = "value"';
let regexp = /\w+/g; // without flag "g", property lastIndex is ignored
regexp.lastIndex = 4;
let word = regexp.exec(str);
alert(word); // varName
Hooray! Problem solved!
We performed a search of \w+, starting from position regexp.lastIndex = 4.
The result is correct.
â¦But wait, not so fast.
Please note: the regexp.exec call starts searching at position lastIndex and then goes further. If thereâs no word at position lastIndex, but itâs somewhere after it, then it will be found:
let str = 'let varName = "value"';
let regexp = /\w+/g;
// start the search from position 3
regexp.lastIndex = 3;
let word = regexp.exec(str);
// found the match at position 4
alert(word[0]); // varName
alert(word.index); // 4
For some tasks, including the lexical analysis, thatâs just wrong. We need to find a match exactly at the given position at the text, not somewhere after it. And thatâs what the flag y is for.
The flag y makes regexp.exec to search exactly at position lastIndex, not âstarting fromâ it.
ÙØ°Ø§ ÙÙ ÙÙØ³ Ø§ÙØ¨ØØ« Ù
ع Ø§ÙØ¹ÙÙ
y:
let str = 'let varName = "value"';
let regexp = /\w+/y;
regexp.lastIndex = 3;
alert( regexp.exec(str) ); // null (there's a space at position 3, not a word)
regexp.lastIndex = 4;
alert( regexp.exec(str) ); // varName (word at position 4)
ÙÙ
ا ÙØ±Ù Ø ÙØ§ ÙØªØ·Ø§Ø¨Ù regexp / \ w + / y Ù٠اÙÙ
ÙØ¶Ø¹3 (عÙÙ Ø¹ÙØ³ Ø§ÙØ¹ÙÙ
g) Ø ÙÙÙÙÙ ÙØªØ·Ø§Ø¨Ù Ù٠اÙÙ
ÙØ¶Ø¹4.
Not only thatâs what we need, thereâs an important performance gain when using flag y.
Imagine, we have a long text, and there are no matches in it, at all. Then a search with flag g will go till the end of the text and find nothing, and this will take significantly more time than the search with flag y, that checks only the exact position.
In tasks like lexical analysis, there are usually many searches at an exact position, to check what we have there. Using flag y is the key for correct implementations and a good performance.

Ø§ÙØªØ¹ÙÙÙØ§Øª
<code>Ø ÙÙÙÙØ«Ùر Ù Ù Ø§ÙØ³Ø·Ùر استخدÙ<pre>Ø ÙÙØ£Ùثر Ù Ù 10 Ø³Ø·ÙØ± استخد٠(plnkr, JSBin, codepenâ¦)