Skip to content

Commit 5033b71

Browse files
authored
Update article.md & all SVGs (#550)
1 parent 3df1300 commit 5033b71

File tree

11 files changed

+33
-33
lines changed

11 files changed

+33
-33
lines changed

9-regular-expressions/10-regexp-greedy-and-lazy/article.md

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,21 @@
1212

1313
Для початку, знайдемо рядки в лапках, аби потім їх замінити.
1414

15-
Регулярний вираз по типу `pattern:/".+"/g` (лапки з чимось всередині) виглядає підходящим, але це не так!
15+
Регулярний вираз по типу `pattern:/".+"/g` (лапки з чимось всередині) виглядає придатним, але це не так!
1616

1717
Спробуємо його на практиці:
1818

1919
```js run
2020
let regexp = /".+"/g;
2121

22-
let str = 'a "witch" and her "broom" is one';
22+
let str = 'я "мавка" ліс моє "єство" та дух';
2323

24-
alert( str.match(regexp) ); // "witch" and her "broom"
24+
alert( str.match(regexp) ); // "мавка" ліс моє "єство"
2525
```
2626

2727
...Як бачимо, вираз працює не так, як очікувалось!
2828

29-
Замість двох збігів `match:"witch"` та `match:"broom"`, він знайшов один: `match:"witch" and her "broom"`.
29+
Замість двох збігів `match:"мавка"` та `match:"єство"`, він знайшов один: `match:"мавка" ліс моє "єство"`.
3030

3131
Про це можна сказати "жадібність -- причина всіх бід".
3232

@@ -42,21 +42,21 @@ alert( str.match(regexp) ); // "witch" and her "broom"
4242

4343
1. Першим символом шаблону є одна з лапок `pattern:"`.
4444

45-
Рушій регулярних виразів намагається знайти його на нульовій позиції вихідного рядку `subject:a "witch" and her "broom" is one`, але бачить `subject:a`, тож вважає, що збігу немає.
45+
Рушій регулярних виразів намагається знайти його на нульовій позиції вихідного рядка `subject:я "мавка" ліс моє "єство" та дух`, але бачить `subject:я`, тож вважає, що збігу немає.
4646

47-
Йдемо далі: бере наступну позицію рядку та намагається на ній знайти перший символ шаблону, знову невдача, але, нарешті, необхідний символ знаходиться на третій позиції:
47+
Йдемо далі: бере наступну позицію рядка та намагається на ній знайти перший символ шаблону, знову невдача, але, нарешті, необхідний символ знаходиться на третій позиції:
4848

4949
![](witch_greedy1.svg)
5050

5151
2. Першу з лапок виявлено, після цього рушій намагається знайти збіг для решти шаблону. Він намагається зрозуміти, чи відповідає решта рядка `pattern:.+"`.
5252

53-
В нашому випадку, наступний символ шаблону -- це `pattern:.` (крапка). Він вказує на "будь-який символ, за винятком символу нового рядку", тож наступна літера рядку `match:'w'` підходить під опис:
53+
В нашому випадку, наступний символ шаблону -- це `pattern:.` (крапка). Він вказує на "будь-який символ, за винятком символу нового рядка", тож наступна літера рядка `match:'м'` підходить під опис:
5454

5555
![](witch_greedy2.svg)
5656

57-
3. Після цього, дія крапки повторюється через наявність квантифікатору `pattern:.+`. Рушій регулярних виразів додає до збігу символи один за одним.
57+
3. Після цього, дія крапки повторюється через наявність квантифікатора `pattern:.+`. Рушій регулярних виразів додає до збігу символи один за одним.
5858

59-
...До якого моменту? Крапка приймає усі символи, таким чином зупиняючись тільки досягнувши кінця рядку:
59+
...До якого моменту? Крапка приймає усі символи, таким чином зупиняючись тільки досягнувши кінця рядка:
6060

6161
![](witch_greedy3.svg)
6262

@@ -68,31 +68,31 @@ alert( str.match(regexp) ); // "witch" and her "broom"
6868

6969
![](witch_greedy4.svg)
7070

71-
Після цього, рушій припускає, що `pattern:.+` завершується одним символом раніше кінця рядку та намагається знайти збіг для решти шаблону, починаючи з тієї позиції.
71+
Після цього, рушій припускає, що `pattern:.+` завершується одним символом раніше кінця рядка та намагається знайти збіг для решти шаблону, починаючи з тієї позиції.
7272

73-
Якби друга з лапок була на цьому місці, то пошук завершився б, але останній символ `subject:'e'` не відповідає цілі пошуку.
73+
Якби друга з лапок була на цьому місці, то пошук завершився б, але останній символ `subject:'х'` не відповідає цілі пошуку.
7474

7575
5. ...Тому рушій зменшує кількість повторів `pattern:.+` на ще один символ:
7676

7777
![](witch_greedy5.svg)
7878

79-
Друга закриваюча лапка `pattern:'"'` не співпадає з `subject:'n'`.
79+
Друга закриваюча лапка `pattern:'"'` не збігається з `subject:'у'`.
8080

8181
6. Рушій продовжує процес повернення: число повторів `pattern:'.'` зменшується доти, доки решта шаблону (в цьому випадку, `pattern:'"'`) не збігається:
8282

8383
![](witch_greedy6.svg)
8484

8585
7. Збіг знайдено.
8686

87-
8. Отож, першим збігом буде:"witch" and her "broom"`. Якщо регулярний вираз має прапорець `pattern:g`, тоді пошук продовжиться з кінця першого збігу. Решта рядку `subject:is one` не містить лапок, тож інших збігів не буде.
87+
8. Отож, першим збігом буде: `"мавка" ліс моє "єство"`. Якщо регулярний вираз має прапорець `pattern:g`, тоді пошук продовжиться з кінця першого збігу. Решта рядка `subject:та дух` не містить лапок, тож інших збігів не буде.
8888

8989
Напевно, це не те, чого ми очікували, але так вже воно працює.
9090

9191
**В жадібному режимі (типово) квантифікований символ повторюється максимально можливу кількість разів.**
9292

9393
Рушій регулярного виразу додає до збігу всі можливі символи для `pattern:.+`, а потім зменшує результат посимвольно, якщо решта шаблону не збігається.
9494

95-
Наша задача потребує іншого підходу. Тут може стати в нагоді лінивий режим.
95+
Наша задача потребує іншого підходу. Тут може стати в пригоді лінивий режим.
9696

9797
## Лінивий режим
9898

@@ -102,17 +102,17 @@ alert( str.match(regexp) ); // "witch" and her "broom"
102102

103103
Пояснимо кілька моментів: зазвичай, знак питання `pattern:?` сам по собі є квантифікатором (0 чи 1), але змінює значення, якщо його додати *після іншого квантифікатора (або навіть самого себе)* -- він змінює режим пошуку з жадібного на лінивий.
104104

105-
Регулярний вираз `pattern:/".+?"/g` працюватиме, як потрібно: він знайде `match:"witch"` та `match:"broom"`:
105+
Регулярний вираз `pattern:/".+?"/g` працюватиме, як потрібно: він знайде `match:"мавка"` та `match:"єство"`:
106106

107107
```js run
108108
let regexp = /".+?"/g;
109109

110-
let str = 'a "witch" and her "broom" is one';
110+
let str = 'я "мавка" ліс моє "єство" та дух';
111111

112-
alert( str.match(regexp) ); // "witch", "broom"
112+
alert( str.match(regexp) ); // "мавка", "єство"
113113
```
114114

115-
Аби чітко побачити різницю, відслідкуємо процес пошуку покроково.
115+
Аби чітко побачити різницю, простежимо процес пошуку покроково.
116116

117117
1. Перший крок той самий: знаходимо початок шаблону `pattern:'"'` на третій позиції:
118118

@@ -126,7 +126,7 @@ alert( str.match(regexp) ); // "witch", "broom"
126126

127127
![](witch_lazy3.svg)
128128

129-
Якби на цьому місці була остання з лапок, тоді пошук закінчився б, але бачимо `'i'`, тож збігу немає.
129+
Якби на цьому місці була остання з лапок, тоді пошук закінчився б, але бачимо `'а'`, тож збігу немає.
130130
4. Далі, рушій регулярних виразів збільшує кількість повторів для крапки та ще раз проводить пошук:
131131

132132
![](witch_lazy4.svg)
@@ -177,9 +177,9 @@ alert( "123 456".match(/\d+ \d+?/) ); // 123 4
177177
```js run
178178
let regexp = /"[^"]+"/g;
179179

180-
let str = 'a "witch" and her "broom" is one';
180+
let str = 'я "мавка" ліс моє "єство" та дух';
181181

182-
alert( str.match(regexp) ); // "witch", "broom"
182+
alert( str.match(regexp) ); // "мавка", "єство"
183183
```
184184

185185
Регулярний вираз `pattern:"[^"]+"` дає правильні результати, бо шукає першу з лапок `pattern:'"'`, за якою слідують один чи більше символів (не лапок) `pattern:[^"]` та друга з лапок в кінці.
@@ -217,7 +217,7 @@ let regexp = /<a href=".*" class="doc">/g;
217217
alert( str.match(regexp) ); // <a href="link1" class="doc">... <a href="link2" class="doc">
218218
```
219219

220-
Тепер результат неправильний з тієї ж причини, що й у прикладі про "witches". Квантифікатор `pattern:.*` бере забагато символів.
220+
Тепер результат неправильний з тієї ж причини, що й у прикладі про "мавку". Квантифікатор `pattern:.*` бере забагато символів.
221221

222222
Збіг виглядає наступним чином:
223223

@@ -293,7 +293,7 @@ alert( str2.match(regexp) ); // <a href="link1" class="doc">, <a href="link2" cl
293293
Квантифікатори мають два режими роботи:
294294

295295
Жадібний
296-
: Типово рушій регулярних виразів намагається повторити квантифікований символ максимально можливу кількість разів. Для прикладу, `pattern:\d+` обирає всі можливі цифри. Коли продовжити цей процес неможливо (більше немає цифр/кінець рядку), тоді продовжується пошук збігу для решти шаблону. Якщо збігу немає, він зменшує кількість повторень (повертається) та пробує наново.
296+
: Типово рушій регулярних виразів намагається повторити квантифікований символ максимально можливу кількість разів. Для прикладу, `pattern:\d+` обирає всі можливі цифри. Коли продовжити цей процес неможливо (більше немає цифр/кінець рядка), тоді продовжується пошук збігу для решти шаблону. Якщо збігу немає, він зменшує кількість повторень (повертається) та пробує наново.
297297

298298
Лінивий
299299
: Включається знаком питання `pattern:?` після квантифікатору. Рушій намагається знайти збіг решти шаблону перед кожним повторенням квантифікованого символу.
Lines changed: 1 addition & 1 deletion
Loading
Lines changed: 1 addition & 1 deletion
Loading

0 commit comments

Comments
 (0)