You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
...Як бачимо, вираз працює не так, як очікувалось!
28
28
29
-
Замість двох збігів `match:"witch"` та `match:"broom"`, він знайшов один: `match:"witch" and her "broom"`.
29
+
Замість двох збігів `match:"мавка"` та `match:"єство"`, він знайшов один: `match:"мавка" ліс моє "єство"`.
30
30
31
31
Про це можна сказати "жадібність -- причина всіх бід".
32
32
@@ -42,21 +42,21 @@ alert( str.match(regexp) ); // "witch" and her "broom"
42
42
43
43
1. Першим символом шаблону є одна з лапок `pattern:"`.
44
44
45
-
Рушій регулярних виразів намагається знайти його на нульовій позиції вихідного рядку`subject:a "witch" and her "broom" is one`, але бачить `subject:a`, тож вважає, що збігу немає.
45
+
Рушій регулярних виразів намагається знайти його на нульовій позиції вихідного рядка`subject:я "мавка" ліс моє "єство" та дух`, але бачить `subject:я`, тож вважає, що збігу немає.
46
46
47
-
Йдемо далі: бере наступну позицію рядку та намагається на ній знайти перший символ шаблону, знову невдача, але, нарешті, необхідний символ знаходиться на третій позиції:
47
+
Йдемо далі: бере наступну позицію рядка та намагається на ній знайти перший символ шаблону, знову невдача, але, нарешті, необхідний символ знаходиться на третій позиції:
48
48
49
49

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

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

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

70
70
71
-
Після цього, рушій припускає, що `pattern:.+` завершується одним символом раніше кінця рядку та намагається знайти збіг для решти шаблону, починаючи з тієї позиції.
71
+
Після цього, рушій припускає, що `pattern:.+` завершується одним символом раніше кінця рядка та намагається знайти збіг для решти шаблону, починаючи з тієї позиції.
72
72
73
-
Якби друга з лапок була на цьому місці, то пошук завершився б, але останній символ `subject:'e'` не відповідає цілі пошуку.
73
+
Якби друга з лапок була на цьому місці, то пошук завершився б, але останній символ `subject:'х'` не відповідає цілі пошуку.
74
74
75
75
5. ...Тому рушій зменшує кількість повторів `pattern:.+` на ще один символ:
76
76
77
77

78
78
79
-
Друга закриваюча лапка `pattern:'"'` не співпадає з `subject:'n'`.
79
+
Друга закриваюча лапка `pattern:'"'` не збігається з `subject:'у'`.
80
80
81
81
6. Рушій продовжує процес повернення: число повторів `pattern:'.'` зменшується доти, доки решта шаблону (в цьому випадку, `pattern:'"'`) не збігається:
82
82
83
83

84
84
85
85
7. Збіг знайдено.
86
86
87
-
8. Отож, першим збігом буде:"witch" and her "broom"`. Якщо регулярний вираз має прапорець `pattern:g`, тоді пошук продовжиться з кінця першого збігу. Решта рядку`subject:is one` не містить лапок, тож інших збігів не буде.
87
+
8. Отож, першим збігом буде:`"мавка" ліс моє "єство"`. Якщо регулярний вираз має прапорець `pattern:g`, тоді пошук продовжиться з кінця першого збігу. Решта рядка`subject:та дух` не містить лапок, тож інших збігів не буде.
88
88
89
89
Напевно, це не те, чого ми очікували, але так вже воно працює.
90
90
91
91
**В жадібному режимі (типово) квантифікований символ повторюється максимально можливу кількість разів.**
92
92
93
93
Рушій регулярного виразу додає до збігу всі можливі символи для `pattern:.+`, а потім зменшує результат посимвольно, якщо решта шаблону не збігається.
94
94
95
-
Наша задача потребує іншого підходу. Тут може стати в нагоді лінивий режим.
95
+
Наша задача потребує іншого підходу. Тут може стати в пригоді лінивий режим.
96
96
97
97
## Лінивий режим
98
98
@@ -102,17 +102,17 @@ alert( str.match(regexp) ); // "witch" and her "broom"
102
102
103
103
Пояснимо кілька моментів: зазвичай, знак питання `pattern:?` сам по собі є квантифікатором (0 чи 1), але змінює значення, якщо його додати *після іншого квантифікатора (або навіть самого себе)* -- він змінює режим пошуку з жадібного на лінивий.
104
104
105
-
Регулярний вираз `pattern:/".+?"/g` працюватиме, як потрібно: він знайде `match:"witch"` та `match:"broom"`:
105
+
Регулярний вираз `pattern:/".+?"/g` працюватиме, як потрібно: він знайде `match:"мавка"` та `match:"єство"`:
106
106
107
107
```js run
108
108
let regexp =/".+?"/g;
109
109
110
-
let str ='a "witch" and her "broom" is one';
110
+
let str ='я "мавка" ліс моє "єство" та дух';
111
111
112
-
alert( str.match(regexp) ); // "witch", "broom"
112
+
alert( str.match(regexp) ); // "мавка", "єство"
113
113
```
114
114
115
-
Аби чітко побачити різницю, відслідкуємо процес пошуку покроково.
115
+
Аби чітко побачити різницю, простежимо процес пошуку покроково.
116
116
117
117
1. Перший крок той самий: знаходимо початок шаблону `pattern:'"'` на третій позиції:
Регулярний вираз `pattern:"[^"]+"` дає правильні результати, бо шукає першу з лапок `pattern:'"'`, за якою слідують один чи більше символів (не лапок) `pattern:[^"]` та друга з лапок в кінці.
@@ -217,7 +217,7 @@ let regexp = /<a href=".*" class="doc">/g;
: Типово рушій регулярних виразів намагається повторити квантифікований символ максимально можливу кількість разів. Для прикладу, `pattern:\d+` обирає всі можливі цифри. Коли продовжити цей процес неможливо (більше немає цифр/кінець рядку), тоді продовжується пошук збігу для решти шаблону. Якщо збігу немає, він зменшує кількість повторень (повертається) та пробує наново.
296
+
: Типово рушій регулярних виразів намагається повторити квантифікований символ максимально можливу кількість разів. Для прикладу, `pattern:\d+` обирає всі можливі цифри. Коли продовжити цей процес неможливо (більше немає цифр/кінець рядка), тоді продовжується пошук збігу для решти шаблону. Якщо збігу немає, він зменшує кількість повторень (повертається) та пробує наново.
297
297
298
298
Лінивий
299
299
: Включається знаком питання `pattern:?` після квантифікатору. Рушій намагається знайти збіг решти шаблону перед кожним повторенням квантифікованого символу.
0 commit comments