diff --git a/9-regular-expressions/10-regexp-greedy-and-lazy/article.md b/9-regular-expressions/10-regexp-greedy-and-lazy/article.md index a8929c241..2c754358e 100644 --- a/9-regular-expressions/10-regexp-greedy-and-lazy/article.md +++ b/9-regular-expressions/10-regexp-greedy-and-lazy/article.md @@ -12,21 +12,21 @@ Для початку, знайдемо рядки в лапках, аби потім їх замінити. -Регулярний вираз по типу `pattern:/".+"/g` (лапки з чимось всередині) виглядає підходящим, але це не так! +Регулярний вираз по типу `pattern:/".+"/g` (лапки з чимось всередині) виглядає придатним, але це не так! Спробуємо його на практиці: ```js run let regexp = /".+"/g; -let str = 'a "witch" and her "broom" is one'; +let str = 'я "мавка" ліс моє "єство" та дух'; -alert( str.match(regexp) ); // "witch" and her "broom" +alert( str.match(regexp) ); // "мавка" ліс моє "єство" ``` ...Як бачимо, вираз працює не так, як очікувалось! -Замість двох збігів `match:"witch"` та `match:"broom"`, він знайшов один: `match:"witch" and her "broom"`. +Замість двох збігів `match:"мавка"` та `match:"єство"`, він знайшов один: `match:"мавка" ліс моє "єство"`. Про це можна сказати "жадібність -- причина всіх бід". @@ -42,21 +42,21 @@ alert( str.match(regexp) ); // "witch" and her "broom" 1. Першим символом шаблону є одна з лапок `pattern:"`. - Рушій регулярних виразів намагається знайти його на нульовій позиції вихідного рядку `subject:a "witch" and her "broom" is one`, але бачить `subject:a`, тож вважає, що збігу немає. + Рушій регулярних виразів намагається знайти його на нульовій позиції вихідного рядка `subject:я "мавка" ліс моє "єство" та дух`, але бачить `subject:я`, тож вважає, що збігу немає. - Йдемо далі: бере наступну позицію рядку та намагається на ній знайти перший символ шаблону, знову невдача, але, нарешті, необхідний символ знаходиться на третій позиції: + Йдемо далі: бере наступну позицію рядка та намагається на ній знайти перший символ шаблону, знову невдача, але, нарешті, необхідний символ знаходиться на третій позиції: ![](witch_greedy1.svg) 2. Першу з лапок виявлено, після цього рушій намагається знайти збіг для решти шаблону. Він намагається зрозуміти, чи відповідає решта рядка `pattern:.+"`. - В нашому випадку, наступний символ шаблону -- це `pattern:.` (крапка). Він вказує на "будь-який символ, за винятком символу нового рядку", тож наступна літера рядку `match:'w'` підходить під опис: + В нашому випадку, наступний символ шаблону -- це `pattern:.` (крапка). Він вказує на "будь-який символ, за винятком символу нового рядка", тож наступна літера рядка `match:'м'` підходить під опис: ![](witch_greedy2.svg) -3. Після цього, дія крапки повторюється через наявність квантифікатору `pattern:.+`. Рушій регулярних виразів додає до збігу символи один за одним. +3. Після цього, дія крапки повторюється через наявність квантифікатора `pattern:.+`. Рушій регулярних виразів додає до збігу символи один за одним. - ...До якого моменту? Крапка приймає усі символи, таким чином зупиняючись тільки досягнувши кінця рядку: + ...До якого моменту? Крапка приймає усі символи, таким чином зупиняючись тільки досягнувши кінця рядка: ![](witch_greedy3.svg) @@ -68,15 +68,15 @@ alert( str.match(regexp) ); // "witch" and her "broom" ![](witch_greedy4.svg) - Після цього, рушій припускає, що `pattern:.+` завершується одним символом раніше кінця рядку та намагається знайти збіг для решти шаблону, починаючи з тієї позиції. + Після цього, рушій припускає, що `pattern:.+` завершується одним символом раніше кінця рядка та намагається знайти збіг для решти шаблону, починаючи з тієї позиції. - Якби друга з лапок була на цьому місці, то пошук завершився б, але останній символ `subject:'e'` не відповідає цілі пошуку. + Якби друга з лапок була на цьому місці, то пошук завершився б, але останній символ `subject:'х'` не відповідає цілі пошуку. 5. ...Тому рушій зменшує кількість повторів `pattern:.+` на ще один символ: ![](witch_greedy5.svg) - Друга закриваюча лапка `pattern:'"'` не співпадає з `subject:'n'`. + Друга закриваюча лапка `pattern:'"'` не збігається з `subject:'у'`. 6. Рушій продовжує процес повернення: число повторів `pattern:'.'` зменшується доти, доки решта шаблону (в цьому випадку, `pattern:'"'`) не збігається: @@ -84,7 +84,7 @@ alert( str.match(regexp) ); // "witch" and her "broom" 7. Збіг знайдено. -8. Отож, першим збігом буде:"witch" and her "broom"`. Якщо регулярний вираз має прапорець `pattern:g`, тоді пошук продовжиться з кінця першого збігу. Решта рядку `subject:is one` не містить лапок, тож інших збігів не буде. +8. Отож, першим збігом буде: `"мавка" ліс моє "єство"`. Якщо регулярний вираз має прапорець `pattern:g`, тоді пошук продовжиться з кінця першого збігу. Решта рядка `subject:та дух` не містить лапок, тож інших збігів не буде. Напевно, це не те, чого ми очікували, але так вже воно працює. @@ -92,7 +92,7 @@ alert( str.match(regexp) ); // "witch" and her "broom" Рушій регулярного виразу додає до збігу всі можливі символи для `pattern:.+`, а потім зменшує результат посимвольно, якщо решта шаблону не збігається. -Наша задача потребує іншого підходу. Тут може стати в нагоді лінивий режим. +Наша задача потребує іншого підходу. Тут може стати в пригоді лінивий режим. ## Лінивий режим @@ -102,17 +102,17 @@ alert( str.match(regexp) ); // "witch" and her "broom" Пояснимо кілька моментів: зазвичай, знак питання `pattern:?` сам по собі є квантифікатором (0 чи 1), але змінює значення, якщо його додати *після іншого квантифікатора (або навіть самого себе)* -- він змінює режим пошуку з жадібного на лінивий. -Регулярний вираз `pattern:/".+?"/g` працюватиме, як потрібно: він знайде `match:"witch"` та `match:"broom"`: +Регулярний вираз `pattern:/".+?"/g` працюватиме, як потрібно: він знайде `match:"мавка"` та `match:"єство"`: ```js run let regexp = /".+?"/g; -let str = 'a "witch" and her "broom" is one'; +let str = 'я "мавка" ліс моє "єство" та дух'; -alert( str.match(regexp) ); // "witch", "broom" +alert( str.match(regexp) ); // "мавка", "єство" ``` -Аби чітко побачити різницю, відслідкуємо процес пошуку покроково. +Аби чітко побачити різницю, простежимо процес пошуку покроково. 1. Перший крок той самий: знаходимо початок шаблону `pattern:'"'` на третій позиції: @@ -126,7 +126,7 @@ alert( str.match(regexp) ); // "witch", "broom" ![](witch_lazy3.svg) - Якби на цьому місці була остання з лапок, тоді пошук закінчився б, але бачимо `'i'`, тож збігу немає. + Якби на цьому місці була остання з лапок, тоді пошук закінчився б, але бачимо `'а'`, тож збігу немає. 4. Далі, рушій регулярних виразів збільшує кількість повторів для крапки та ще раз проводить пошук: ![](witch_lazy4.svg) @@ -177,9 +177,9 @@ alert( "123 456".match(/\d+ \d+?/) ); // 123 4 ```js run let regexp = /"[^"]+"/g; -let str = 'a "witch" and her "broom" is one'; +let str = 'я "мавка" ліс моє "єство" та дух'; -alert( str.match(regexp) ); // "witch", "broom" +alert( str.match(regexp) ); // "мавка", "єство" ``` Регулярний вираз `pattern:"[^"]+"` дає правильні результати, бо шукає першу з лапок `pattern:'"'`, за якою слідують один чи більше символів (не лапок) `pattern:[^"]` та друга з лапок в кінці. @@ -217,7 +217,7 @@ let regexp = //g; alert( str.match(regexp) ); // ... ``` -Тепер результат неправильний з тієї ж причини, що й у прикладі про "witches". Квантифікатор `pattern:.*` бере забагато символів. +Тепер результат неправильний з тієї ж причини, що й у прикладі про "мавку". Квантифікатор `pattern:.*` бере забагато символів. Збіг виглядає наступним чином: @@ -293,7 +293,7 @@ alert( str2.match(regexp) ); // , a "witch" and her "broom" is one \ No newline at end of file +я "мавка" ліс моє "єство" та дух diff --git a/9-regular-expressions/10-regexp-greedy-and-lazy/witch_greedy2.svg b/9-regular-expressions/10-regexp-greedy-and-lazy/witch_greedy2.svg index f821c6d8c..4ff1d50f6 100644 --- a/9-regular-expressions/10-regexp-greedy-and-lazy/witch_greedy2.svg +++ b/9-regular-expressions/10-regexp-greedy-and-lazy/witch_greedy2.svg @@ -1 +1 @@ -a "witch" and her "broom" is one \ No newline at end of file +я "мавка" ліс моє "єство" та дух diff --git a/9-regular-expressions/10-regexp-greedy-and-lazy/witch_greedy3.svg b/9-regular-expressions/10-regexp-greedy-and-lazy/witch_greedy3.svg index 9509882b2..83bbab389 100644 --- a/9-regular-expressions/10-regexp-greedy-and-lazy/witch_greedy3.svg +++ b/9-regular-expressions/10-regexp-greedy-and-lazy/witch_greedy3.svg @@ -1 +1 @@ -a "witch" and her "broom" is one \ No newline at end of file +я "мавка" ліс моє "єство" та дух diff --git a/9-regular-expressions/10-regexp-greedy-and-lazy/witch_greedy4.svg b/9-regular-expressions/10-regexp-greedy-and-lazy/witch_greedy4.svg index 8c5532b9f..ca3f5a568 100644 --- a/9-regular-expressions/10-regexp-greedy-and-lazy/witch_greedy4.svg +++ b/9-regular-expressions/10-regexp-greedy-and-lazy/witch_greedy4.svg @@ -1 +1 @@ -a "witch" and her "broom" is one \ No newline at end of file +я "мавка" ліс моє "єство" та дух diff --git a/9-regular-expressions/10-regexp-greedy-and-lazy/witch_greedy5.svg b/9-regular-expressions/10-regexp-greedy-and-lazy/witch_greedy5.svg index 29cb0c533..0206f7927 100644 --- a/9-regular-expressions/10-regexp-greedy-and-lazy/witch_greedy5.svg +++ b/9-regular-expressions/10-regexp-greedy-and-lazy/witch_greedy5.svg @@ -1 +1 @@ -a "witch" and her "broom" is one \ No newline at end of file +я "мавка" ліс моє "єство" та дух diff --git a/9-regular-expressions/10-regexp-greedy-and-lazy/witch_greedy6.svg b/9-regular-expressions/10-regexp-greedy-and-lazy/witch_greedy6.svg index 9f4b78b07..60bb4a42b 100644 --- a/9-regular-expressions/10-regexp-greedy-and-lazy/witch_greedy6.svg +++ b/9-regular-expressions/10-regexp-greedy-and-lazy/witch_greedy6.svg @@ -1 +1 @@ -a "witch" and her "broom" is one \ No newline at end of file +я "мавка" ліс моє "єство" та дух diff --git a/9-regular-expressions/10-regexp-greedy-and-lazy/witch_lazy3.svg b/9-regular-expressions/10-regexp-greedy-and-lazy/witch_lazy3.svg index 06b2b5f17..2353c0369 100644 --- a/9-regular-expressions/10-regexp-greedy-and-lazy/witch_lazy3.svg +++ b/9-regular-expressions/10-regexp-greedy-and-lazy/witch_lazy3.svg @@ -1 +1 @@ -a "witch" and her "broom" is one \ No newline at end of file +я "мавка" ліс моє "єство" та дух diff --git a/9-regular-expressions/10-regexp-greedy-and-lazy/witch_lazy4.svg b/9-regular-expressions/10-regexp-greedy-and-lazy/witch_lazy4.svg index 60a09b565..a15d7cbdf 100644 --- a/9-regular-expressions/10-regexp-greedy-and-lazy/witch_lazy4.svg +++ b/9-regular-expressions/10-regexp-greedy-and-lazy/witch_lazy4.svg @@ -1 +1 @@ -a "witch" and her "broom" is one \ No newline at end of file +я "мавка" ліс моє "єство" та дух diff --git a/9-regular-expressions/10-regexp-greedy-and-lazy/witch_lazy5.svg b/9-regular-expressions/10-regexp-greedy-and-lazy/witch_lazy5.svg index cec5b5d7c..f8e86ea12 100644 --- a/9-regular-expressions/10-regexp-greedy-and-lazy/witch_lazy5.svg +++ b/9-regular-expressions/10-regexp-greedy-and-lazy/witch_lazy5.svg @@ -1 +1 @@ -a "witch" and her "broom" is one \ No newline at end of file +я "мавка" ліс моє "єство" та дух diff --git a/9-regular-expressions/10-regexp-greedy-and-lazy/witch_lazy6.svg b/9-regular-expressions/10-regexp-greedy-and-lazy/witch_lazy6.svg index db040e558..cba395f83 100644 --- a/9-regular-expressions/10-regexp-greedy-and-lazy/witch_lazy6.svg +++ b/9-regular-expressions/10-regexp-greedy-and-lazy/witch_lazy6.svg @@ -1 +1 @@ -a "witch" and her "broom" is one \ No newline at end of file +я "мавка" ліс моє "єство" та дух