Skip to content

Commit 233dde1

Browse files
committed
RegExp greedy and lazy quantifiers: two headers
1 parent 9aa1989 commit 233dde1

1 file changed

Lines changed: 39 additions & 39 deletions

File tree

  • 9-regular-expressions/08-regexp-greedy-and-lazy

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

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
# Greedy and lazy quantifiers
1+
# Жадные и ленивые квантификаторы
22

3-
Quantifiers are very simple from the first sight, but in fact they can be tricky.
3+
На первый взгляд квантификаторы очень просты, но на самом деле, всё не так просто.
44

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+/`.
66

7-
Let's take the following task as an example.
7+
Давайте, в качестве примера, рассмотрим следующую задачу:
88

9-
We have a text and need to replace all quotes `"..."` with guillemet marks: `«...»`. They are preferred for typography in many countries.
9+
У нас есть текст, в котором нужно заменить все кавычки `"..."` на "ёлочки": `«...»`. Которые используются в типографике многих стран.
1010

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!”` (польский) или `「你好,世界」` (китайский), но для нашей задачи давайте выберем `«...»`.
1212

13-
The first thing to do is to locate quoted strings, and then we can replace them.
13+
Первое, что нам нужно, это найти строки с кавычками, а затем -- мы можем их заменить.
1414

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` (кавычка, какой-то текст, другая кавычка) может выглядеть хорошим решением, но это не так!
1616

17-
Let's try it:
17+
Давайте проверим это:
1818

1919
```js run
2020
let reg = /".+"/g;
@@ -24,75 +24,75 @@ let str = 'a "witch" and her "broom" is one';
2424
alert( str.match(reg) ); // "witch" and her "broom"
2525
```
2626

27-
...We can see that it works not as intended!
27+
...Как мы видим, это работает не как задумано!
2828

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"`.
3030

31-
That can be described as "greediness is the cause of all evil".
31+
Это можно описать, как "жадность -- причина всех зол".
3232

33-
## Greedy search
33+
## Жадный поиск
3434

35-
To find a match, the regular expression engine uses the following algorithm:
35+
Чтобы найти совпадение, движок регулярного выражения следует следующему алгоритму:
3636

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+
- Если нет совпадения, переход к следующей позиции
4040

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:".+"`.
4242

43-
1. The first pattern character is a quote `pattern:"`.
43+
1. Первый символ шаблона -- это кавычка `pattern:"`.
4444

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`, так что совпадения сразу нет.
4646

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+
Затем он продолжает: двигается к следующей позиции исходной строки и пытается найти первый символ шаблона там. И, наконец, находит кавычку на третьей позиции:
4848

4949
![](witch_greedy1.png)
5050

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:.+"`.
5252

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'` подходит.
5454

5555
![](witch_greedy2.png)
5656

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:.+`. Движок регулярного выражения строит совпадение, беря символы один за другим, пока это возможно.
5858

59-
...When it becomes impossible? All characters match the dot, so it only stops when it reaches the end of the string:
59+
...Когда же это перестанет быть возможным? Точке соответствуют любые символы, так что движок остановется только тогда, когда достигнет конца строки:
6060

6161
![](witch_greedy3.png)
6262

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:"`. Но есть проблема: строка закончилась, больше нет символов!
6464

65-
The regular expression engine understands that it took too many `pattern:.+` and starts to *backtrack*.
65+
Движок регулярного выражения понимает, что захватил слишком много `pattern:.+` и начинает *отступать*.
6666

67-
In other words, it shortens the match for the quantifier by one character:
67+
Другими словами, он сокращает совпадение по квантификатору на один символ:
6868

6969
![](witch_greedy4.png)
7070

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:.+` заканчивается за один символ до конца строки и пытается сопоставить остаток шаблона для этой позиции.
7272

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'`, так что он не подходит.
7474

75-
5. ...So the engine decreases the number of repetitions of `pattern:.+` by one more character:
75+
5. ...Поэтому движок уменьшает количество повторений `pattern:.+` на ещё один символ:
7676

7777
![](witch_greedy5.png)
7878

79-
The quote `pattern:'"'` does not match `subject:'n'`.
79+
Кавычка `pattern:'"'`не соответствует `subject:'n'`.
8080

81-
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:'"'`) не совпадёт:
8282

8383
![](witch_greedy6.png)
8484

85-
7. The match is complete.
85+
7. Совпадение найдено.
8686

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` нет кавычек, так что совпадений больше нет.
8888

89-
That's probably not what we expected, but that's how it works.
89+
Это определённо не то, что мы ожидали. Но так оно работает.
9090

91-
**In the greedy mode (by default) the quantifier is repeated as many times as possible.**
91+
**В жадном режиме (по умолчанию) квантификатор повторяется столько раз, сколько это возможно.**
9292

93-
The regexp engine tries to fetch as many characters as it can by `pattern:.+`, and then shortens that one by one.
93+
Движок регулярного выражения пытается получить максимальное количество символов соответствующих `pattern:.+`, а потом сократить это количество символ за символом.
9494

95-
For our task we want another thing. That's what the lazy quantifier mode is for.
95+
Для нашей задачи мы хотим другого. Именно для этого и создан "ленивый" квантификатор.
9696

9797
## Lazy mode
9898

0 commit comments

Comments
 (0)