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
Copy file name to clipboardExpand all lines: 9-regular-expressions/08-regexp-greedy-and-lazy/article.md
+39-39Lines changed: 39 additions & 39 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,20 +1,20 @@
1
-
# Greedy and lazy quantifiers
1
+
# Жадные и ленивые квантификаторы
2
2
3
-
Quantifiers are very simple from the first sight, but in fact they can be tricky.
3
+
На первый взгляд квантификаторы очень просты, но на самом деле, всё не так просто.
4
4
5
-
We should understand how the search works very well if we plan to look for something more complex than`pattern:/\d+/`.
5
+
Нужно очень хорошо разбираться, как работает поиск, если планируешь использовать что-то более сложное, чем:`pattern:/\d+/`.
6
6
7
-
Let's take the following task as an example.
7
+
Давайте, в качестве примера, рассмотрим следующую задачу:
8
8
9
-
We have a text and need to replace all quotes`"..."`with guillemet marks: `«...»`. They are preferred for typography in many countries.
9
+
У нас есть текст, в котором нужно заменить все кавычки`"..."`на "ёлочки": `«...»`. Которые используются в типографике многих стран.
10
10
11
-
For instance: `"Hello, world"`should become `«Hello, world»`. Some countries prefer other quotes, like`„Witam, świat!”` (Polish) or`「你好,世界」` (Chinese), but for our task let's choose`«...»`.
11
+
Например: `"Привет, мир"`должно превратиться в `«Привет, мир»`. Некоторые страны предпочитают другие кавычки, вроде`„Witam, świat!”` (польский) или`「你好,世界」` (китайский), но для нашей задачи давайте выберем`«...»`.
12
12
13
-
The first thing to do is to locate quoted strings, and then we can replace them.
13
+
Первое, что нам нужно, это найти строки с кавычками, а затем -- мы можем их заменить.
14
14
15
-
A regular expression like `pattern:/".+"/g` (a quote, then something, then the other quote) may seem like a good fit, but it isn't!
15
+
Регулярное выражение вроде `pattern:/".+"/g` (кавычка, какой-то текст, другая кавычка) может выглядеть хорошим решением, но это не так!
16
16
17
-
Let's try it:
17
+
Давайте проверим это:
18
18
19
19
```js run
20
20
let reg =/".+"/g;
@@ -24,75 +24,75 @@ let str = 'a "witch" and her "broom" is one';
24
24
alert( str.match(reg) ); // "witch" and her "broom"
25
25
```
26
26
27
-
...We can see that it works not as intended!
27
+
...Как мы видим, это работает не как задумано!
28
28
29
-
Instead of finding two matches `match:"witch"`and`match:"broom"`, it finds one: `match:"witch" and her "broom"`.
29
+
Вместо того, чтобы найти два совпадения `match:"width"`и`match:"broom"`, было найдено одно:`match:"witch" and her "broom"`.
30
30
31
-
That can be described as "greediness is the cause of all evil".
31
+
Это можно описать, как "жадность -- причина всех зол".
32
32
33
-
## Greedy search
33
+
## Жадный поиск
34
34
35
-
To find a match, the regular expression engine uses the following algorithm:
35
+
Чтобы найти совпадение, движок регулярного выражения следует следующему алгоритму:
36
36
37
-
-For every position in the string
38
-
-Match the pattern at that position.
39
-
-If there's no match, go to the next position.
37
+
-Для каждой позиции в строке
38
+
-Совпадение шаблона на текущей позиции
39
+
-Если нет совпадения, переход к следующей позиции
40
40
41
-
These common words do not make it obvious why the regexp fails, so let's elaborate how the search works for the pattern`pattern:".+"`.
41
+
Эти общие слова никак не объясняют, почему регулярное выражение работает неправильно, так что давайте разберём подробно, как работает шаблон`pattern:".+"`.
42
42
43
-
1.The first pattern character is a quote`pattern:"`.
43
+
1.Первый символ шаблона -- это кавычка`pattern:"`.
44
44
45
-
The regular expression engine tries to find it at the zero position of the source string `subject:a "witch" and her "broom" is one`, but there's `subject:a` there, so there's immediately no match.
45
+
Движок регулярного выражения пытается найти его на нулевой позиции исходной строки `subject:a "witch" and her "broom" is one`, но там находится `subject:a`, так что совпадения сразу нет.
46
46
47
-
Then it advances: goes to the next positions in the source string and tries to find the first character of the pattern there, and finally finds the quote at the 3rd position:
47
+
Затем он продолжает: двигается к следующей позиции исходной строки и пытается найти первый символ шаблона там. И, наконец, находит кавычку на третьей позиции:
48
48
49
49

50
50
51
-
2.The quote is detected, and then the engine tries to find a match for the rest of the pattern. It tries to see if the rest of the subject string conforms to`pattern:.+"`.
51
+
2.Кавычка замечена, после чего движок пытается найти совпадение для оставшегося шаблона. Пытается увидеть, удовлетворяет ли остаток строки шаблону`pattern:.+"`.
52
52
53
-
In our case the next pattern character is `pattern:.` (a dot). It denotes "any character except a newline", so the next string letter`match:'w'`fits:
53
+
В нашем случае следующий символ шаблона: `pattern:.` (точка). Она обозначает "любой символ, кроме новой строки", так что следующая буква строки`match:'w'`подходит.
54
54
55
55

56
56
57
-
3.Then the dot repeats because of the quantifier `pattern:.+`. The regular expression engine builds the match by taking characters one by one while it is possible.
57
+
3.Затем точка повторяется из-за квантификатора `pattern:.+`. Движок регулярного выражения строит совпадение, беря символы один за другим, пока это возможно.
58
58
59
-
...When it becomes impossible? All characters match the dot, so it only stops when it reaches the end of the string:
59
+
...Когда же это перестанет быть возможным? Точке соответствуют любые символы, так что движок остановется только тогда, когда достигнет конца строки:
60
60
61
61

62
62
63
-
4.Now the engine finished repeating for `pattern:.+`and tries to find the next character of the pattern. It's the quote `pattern:"`. But there's a problem: the string has finished, there are no more characters!
63
+
4.Тогда движок перестанет повторяться для `pattern:.+`и попробует найти следующий символ шаблона. Это кавычка `pattern:"`. Но есть проблема: строка закончилась, больше нет символов!
64
64
65
-
The regular expression engine understands that it took too many `pattern:.+`and starts to *backtrack*.
65
+
Движок регулярного выражения понимает, что захватил слишком много `pattern:.+`и начинает *отступать*.
66
66
67
-
In other words, it shortens the match for the quantifier by one character:
67
+
Другими словами, он сокращает совпадение по квантификатору на один символ:
68
68
69
69

70
70
71
-
Now it assumes that`pattern:.+`ends one character before the end and tries to match the rest of the pattern from that position.
71
+
Теперь он предполагает, что`pattern:.+`заканчивается за один символ до конца строки и пытается сопоставить остаток шаблона для этой позиции.
72
72
73
-
If there were a quote there, then that would be the end, but the last character is`subject:'e'`, so there's no match.
73
+
Если бы тут была кавычка, тогда бы работа закончилась, но последний символ -- это`subject:'e'`, так что он не подходит.
74
74
75
-
5. ...So the engine decreases the number of repetitions of `pattern:.+`by one more character:
75
+
5. ...Поэтому движок уменьшает количество повторений `pattern:.+`на ещё один символ:
76
76
77
77

78
78
79
-
The quote `pattern:'"'` does not match`subject:'n'`.
6.The engine keep backtracking: it decreases the count of repetition for `pattern:'.'`until the rest of the pattern (in our case`pattern:'"'`) matches:
81
+
6.Движок продолжает отступать: он уменьшает количество повторений `pattern:'.'`пока оставшийся шаблон (в нашем случае`pattern:'"'`) не совпадёт:
82
82
83
83

84
84
85
-
7.The match is complete.
85
+
7.Совпадение найдено.
86
86
87
-
8.So the first match is `match:"witch" and her "broom"`. The further search starts where the first match ends, but there are no more quotes in the rest of the string `subject:is one`, so no more results.
87
+
8.Так что первое совпадение: `match:"witch" and her "boom"`. Дальнейший поиск продолжается с того места, где закончился предыдущий, в оставшейся строке `subject:is one` нет кавычек, так что совпадений больше нет.
88
88
89
-
That's probably not what we expected, but that's how it works.
89
+
Это определённо не то, что мы ожидали. Но так оно работает.
90
90
91
-
**In the greedy mode (by default) the quantifier is repeated as many times as possible.**
91
+
**В жадном режиме (по умолчанию) квантификатор повторяется столько раз, сколько это возможно.**
92
92
93
-
The regexp engine tries to fetch as many characters as it can by `pattern:.+`, and then shortens that one by one.
93
+
Движок регулярного выражения пытается получить максимальное количество символов соответствующих `pattern:.+`, а потом сократить это количество символ за символом.
94
94
95
-
For our task we want another thing. That's what the lazy quantifier mode is for.
95
+
Для нашей задачи мы хотим другого. Именно для этого и создан "ленивый" квантификатор.
0 commit comments