Skip to content

Commit cb54730

Browse files
Merge pull request #220 from NancyT33333/11-regexp-alternation
9-regular-expressions/11-regexp-alternation/
2 parents 7aec631 + a6a87f6 commit cb54730

File tree

9 files changed

+103
-103
lines changed

9 files changed

+103
-103
lines changed

9-regular-expressions/11-regexp-alternation/01-find-programming-language/solution.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

2-
The first idea can be to list the languages with `|` in-between.
2+
Первая идея, которая может прийти в голову -- перечислить языки, разделив их `|`.
33

4-
But that doesn't work right:
4+
Но это не сработает, как надо:
55

66
```js run
77
let reg = /Java|JavaScript|PHP|C|C\+\+/g;
@@ -11,18 +11,18 @@ let str = "Java, JavaScript, PHP, C, C++";
1111
alert( str.match(reg) ); // Java,Java,PHP,C,C
1212
```
1313

14-
The regular expression engine looks for alternations one-by-one. That is: first it checks if we have `match:Java`, otherwise -- looks for `match:JavaScript` and so on.
14+
Движок регулярных выражений ищет альтернации в порядке их перечисления. То есть, он сначала смотрит, есть ли `match:Java`, а если нет -- ищет `match:JavaScript` и так далее.
1515

16-
As a result, `match:JavaScript` can never be found, just because `match:Java` is checked first.
16+
В результате `match:JavaScript` не будет найден никогда, только потому что `match:Java` проверяется первым.
1717

18-
The same with `match:C` and `match:C++`.
18+
То же самое -- с языками `match:C` и `match:C++`.
1919

20-
There are two solutions for that problem:
20+
Есть два решения проблемы:
2121

22-
1. Change the order to check the longer match first: `pattern:JavaScript|Java|C\+\+|C|PHP`.
23-
2. Merge variants with the same start: `pattern:Java(Script)?|C(\+\+)?|PHP`.
22+
1. Поменять порядок, чтобы более длинное совпадение проверялось первым: `pattern:JavaScript|Java|C\+\+|C|PHP`.
23+
2. Соединить одинаково начинающиеся варианты: `pattern:Java(Script)?|C(\+\+)?|PHP`.
2424

25-
In action:
25+
В действии:
2626

2727
```js run
2828
let reg = /Java(Script)?|C(\+\+)?|PHP/g;
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
# Find programming languages
1+
# Найдите языки программирования
22

3-
There are many programming languages, for instance Java, JavaScript, PHP, C, C++.
3+
Существует много языков программирования, например, Java, JavaScript, PHP, C, C++.
44

5-
Create a regexp that finds them in the string `subject:Java JavaScript PHP C++ C`:
5+
Напишите регулярное выражение, которое найдёт их все в строке `subject:Java JavaScript PHP C++ C`:
66

77
```js
8-
let reg = /your regexp/g;
8+
let reg = /ваше регулярное выражение/флаги;
99

1010
alert("Java JavaScript PHP C++ C".match(reg)); // Java JavaScript PHP C++ C
1111
```
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11

2-
Opening tag is `pattern:\[(b|url|quote)\]`.
2+
Открывающий тег -- это `pattern:\[(b|url|quote)\]`.
33

4-
Then to find everything till the closing tag -- let's use the pattern `pattern:.*?` with flag `s` to match any character including the newline and then add a backreference to the closing tag.
4+
Затем, чтобы найти всё до закрывающего тега -- используем выражение `pattern:.*?` с флагом `s`: оно найдет любые символы, включая новую строку, и затем добавим обратную ссылку на открывающий тег.
55

6-
The full pattern: `pattern:\[(b|url|quote)\].*?\[/\1\]`.
6+
Полное выражение: `pattern:\[(b|url|quote)\].*?\[/\1\]`.
77

8-
In action:
8+
В действии:
99

1010
```js run
11-
let reg = /\[(b|url|quote)\].*?\[\/\1\]/gs;
11+
let reg = /[(b|url|quote)].*?[/\1]/gs;
1212

1313
let str = `
14-
[b]hello![/b]
14+
[b]привет![/b]
1515
[quote]
16-
[url]http://google.com[/url]
16+
[url]http://ya.ru[/url]
1717
[/quote]
1818
`;
1919

20-
alert( str.match(reg) ); // [b]hello![/b],[quote][url]http://google.com[/url][/quote]
20+
alert( str.match(reg) ); // [b]привет![/b],[quote][url]http://ya.ru[/url][/quote]
2121
```
2222

23-
Please note that we had to escape a slash for the closing tag `pattern:[/\1]`, because normally the slash closes the pattern.
23+
Обратите внимание, что необходимо экранировать слеш `pattern:[/\1]`, потому что обычно слеш завершает паттерн.
Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,48 @@
1-
# Find bbtag pairs
1+
# Найдите пары BB-кодов
22

3-
A "bb-tag" looks like `[tag]...[/tag]`, where `tag` is one of: `b`, `url` or `quote`.
3+
[BB-код](https://ru.wikipedia.org/wiki/BBCode) имеет вид `[tag]...[/tag]`, где `tag`-- это один из: `b`, `url` или `quote`.
44

5-
For instance:
5+
Например:
66
```
7-
[b]text[/b]
8-
[url]http://google.com[/url]
7+
[b]текст[/b]
8+
[url]http://ya.ru[/url]
99
```
1010

11-
BB-tags can be nested. But a tag can't be nested into itself, for instance:
11+
BB-коды могут быть вложенными. Но сам в себя тег быть вложен не может, например:
1212

1313
```
14-
Normal:
15-
[url] [b]http://google.com[/b] [/url]
16-
[quote] [b]text[/b] [/quote]
14+
Допустимо:
15+
[url] [b]http://ya.ru[/b] [/url]
16+
[quote] [b]текст[/b] [/quote]
1717
18-
Impossible:
19-
[b][b]text[/b][/b]
18+
Нельзя:
19+
[b][b]текст[/b][/b]
2020
```
2121

22-
Tags can contain line breaks, that's normal:
22+
Теги могут содержать переносы строк, это допустимо:
2323

2424
```
2525
[quote]
26-
[b]text[/b]
26+
[b]текст[/b]
2727
[/quote]
2828
```
2929

30-
Create a regexp to find all BB-tags with their contents.
30+
Создайте регулярное выражение для поиска всех BB-кодов и их содержимого.
3131

32-
For instance:
32+
Например:
3333

3434
```js
35-
let reg = /your regexp/flags;
35+
let reg = /ваше регулярное выражение/флаги;
3636

37-
let str = "..[url]http://google.com[/url]..";
38-
alert( str.match(reg) ); // [url]http://google.com[/url]
37+
let str = "..[url]http://ya.ru[/url]..";
38+
alert( str.match(reg) ); // [url]http://ya.ru[/url]
3939
```
4040

41-
If tags are nested, then we need the outer tag (if we want we can continue the search in its content):
41+
Если теги вложены, то нужно искать самый внешний тег (при желании можно продолжить поиск в его содержимом):
4242

4343
```js
44-
let reg = /your regexp/flags;
44+
let reg = /ваше регулярное выражение/флаги;
4545

46-
let str = "..[url][b]http://google.com[/b][/url]..";
47-
alert( str.match(reg) ); // [url][b]http://google.com[/b][/url]
46+
let str = "..[url][b]http://ya.ru[/b][/url]..";
47+
alert( str.match(reg) ); // [url][b]http://ya.ru[/b][/url]
4848
```
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
The solution: `pattern:/"(\\.|[^"\\])*"/g`.
1+
Решение: `pattern:/"(\\.|[^"\\])*"/g`.
22

3-
Step by step:
3+
Шаг за шагом:
44

5-
- First we look for an opening quote `pattern:"`
6-
- Then if we have a backslash `pattern:\\` (we technically have to double it in the pattern, because it is a special character, so that's a single backslash in fact), then any character is fine after it (a dot).
7-
- Otherwise we take any character except a quote (that would mean the end of the string) and a backslash (to prevent lonely backslashes, the backslash is only used with some other symbol after it): `pattern:[^"\\]`
8-
- ...And so on till the closing quote.
5+
- Сначала ищем открывающую кавычку `pattern:"`
6+
- Затем, если есть обратный слеш `pattern:\\` (удвоение обратного слеша – техническое, потому что это спец.символ, на самом деле там один обратный слеш), то после него также подойдёт любой символ (точка).
7+
- Иначе берём любой символ, кроме кавычек (которые будут означать конец строки) и обратного слеша (чтобы предотвратить одинокие обратные слеши, сам по себе единственный обратный слеш не нужен, он должен экранировать какой-то символ) `pattern:[^"\\]`
8+
- ...И так далее, до закрывающей кавычки.
99

10-
In action:
10+
В действии:
1111

1212
```js run
1313
let reg = /"(\\.|[^"\\])*"/g;
14-
let str = ' .. "test me" .. "Say \\"Hello\\"!" .. "\\\\ \\"" .. ';
14+
let str = ' .. "test me" .. "Скажи \\"Привет\\"!" .. "\\\\ \\"" .. ';
1515

16-
alert( str.match(reg) ); // "test me","Say \"Hello\"!","\\ \""
16+
alert( str.match(reg) ); // "test me","Скажи \"Привет\"!","\\ \""
1717
```
Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,32 @@
1-
# Find quoted strings
1+
# Найдите строки в кавычках
22

3-
Create a regexp to find strings in double quotes `subject:"..."`.
3+
Создайте регулярное выражение для поиска строк в двойных кавычках `subject:"..."`.
44

5-
The strings should support escaping, the same way as JavaScript strings do. For instance, quotes can be inserted as `subject:\"` a newline as `subject:\n`, and the slash itself as `subject:\\`.
5+
Важно, что строки должны поддерживать экранирование с помощью обратного слеша, по аналогии со строками JavaScript. Например, кавычки могут быть вставлены как `subject:\"`, новая строка как `subject:\n`, а сам обратный слеш как `subject:\\`.
66

77
```js
8-
let str = "Just like \"here\".";
8+
let str = "Как вот \"здесь\".";
99
```
1010

11-
Please note, in particular, that an escaped quote `subject:\"` does not end a string.
11+
В частности, обратите внимание: двойная кавычка после обратного слеша `subject:\"` не оканчивает строку.
1212

13-
So we should search from one quote to the other ignoring escaped quotes on the way.
13+
Поэтому мы должны искать от одной кавычки до другой, игнорируя встречающиеся экранированные кавычки.
1414

15-
That's the essential part of the task, otherwise it would be trivial.
15+
В этом и состоит основная сложность задачи, которая без этого условия была бы элементарной.
1616

17-
Examples of strings to match:
17+
Примеры подходящих строк:
1818
```js
1919
.. *!*"test me"*/!* ..
20-
.. *!*"Say \"Hello\"!"*/!* ... (escaped quotes inside)
21-
.. *!*"\\"*/!* .. (double slash inside)
22-
.. *!*"\\ \""*/!* .. (double slash and an escaped quote inside)
20+
.. *!*"Скажи \"Привет\"!"*/!* ... (строка с экранированными кавычками)
21+
.. *!*"\\"*/!* .. (внутри двойной слеш)
22+
.. *!*"\\ \""*/!* .. (внутри двойной слеш и экранированная кавычка)
2323
```
2424

25-
In JavaScript we need to double the slashes to pass them right into the string, like this:
25+
В JavaScript приходится удваивать обратные слеши, чтобы добавлять их в строку, как здесь:
2626

2727
```js run
28-
let str = ' .. "test me" .. "Say \\"Hello\\"!" .. "\\\\ \\"" .. ';
28+
let str = ' .. "test me" .. "Скажи \\"Привет\\"!" .. "\\\\ \\"" .. ';
2929

30-
// the in-memory string
31-
alert(str); // .. "test me" .. "Say \"Hello\"!" .. "\\ \"" ..
30+
// эта строка в памяти:
31+
alert(str); // .. "test me" .. "Скажи \"Привет\"!" .. "\\ \"" ..
3232
```

9-regular-expressions/11-regexp-alternation/04-match-exact-tag/solution.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11

2-
The pattern start is obvious: `pattern:<style`.
2+
Начало шаблона очевидно: `pattern:<style`.
33

4-
...But then we can't simply write `pattern:<style.*?>`, because `match:<styler>` would match it.
4+
...А вот дальше… Мы не можем написать просто `pattern:<style.*?>`, потому что `match:<styler>` удовлетворяет этому выражению.
55

6-
We need either a space after `match:<style` and then optionally something else or the ending `match:>`.
6+
После `match:<style` должен быть либо пробел, после которого может быть что-то ещё, либо закрытие тега `match:>`.
77

8-
In the regexp language: `pattern:<style(>|\s.*?>)`.
8+
На языке регулярных выражений: `pattern:<style(>|\s.*?>)`.
99

10-
In action:
10+
В действии:
1111

1212
```js run
1313
let reg = /<style(>|\s.*?>)/g;
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
# Find the full tag
1+
# Найдите весь тег
22

3-
Write a regexp to find the tag `<style...>`. It should match the full tag: it may have no attributes `<style>` or have several of them `<style type="..." id="...">`.
3+
Напишите регулярное выражение, которое ищет тег `<style...>`. Оно должно искать весь тег: он может как не иметь атрибутов `<style>`, так и иметь несколько `<style type="..." id="...">`.
44

5-
...But the regexp should not match `<styler>`!
5+
...Но регулярное выражение не должно находить `<styler>`!
66

7-
For instance:
7+
Например:
88

99
```js
10-
let reg = /your regexp/g;
10+
let reg = /ваше регулярное выражение/g;
1111

1212
alert( '<style> <styler> <style test="...">'.match(reg) ); // <style>, <style test="...">
1313
```

9-regular-expressions/11-regexp-alternation/article.md

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,56 @@
1-
# Alternation (OR) |
1+
# Альтернация (или) |
22

3-
Alternation is the term in regular expression that is actually a simple "OR".
3+
Альтернация – термин в регулярных выражениях, которому в русском языке соответствует слово «ИЛИ».
44

5-
In a regular expression it is denoted with a vertical line character `pattern:|`.
5+
В регулярных выражениях она обозначается символом вертикальной черты `pattern:|`.
66

7-
For instance, we need to find programming languages: HTML, PHP, Java or JavaScript.
7+
Например, нам нужно найти языки программирования: HTML, PHP, Java и JavaScript.
88

9-
The corresponding regexp: `pattern:html|php|java(script)?`.
9+
Соответствующее регулярное выражение: `pattern:html|php|java(script)?`.
1010

11-
A usage example:
11+
Пример использования:
1212

1313
```js run
1414
let reg = /html|php|css|java(script)?/gi;
1515

16-
let str = "First HTML appeared, then CSS, then JavaScript";
16+
let str = "Сначала появился HTML, затем CSS, потом JavaScript";
1717

1818
alert( str.match(reg) ); // 'HTML', 'CSS', 'JavaScript'
1919
```
2020

21-
We already know a similar thing -- square brackets. They allow to choose between multiple character, for instance `pattern:gr[ae]y` matches `match:gray` or `match:grey`.
21+
Мы уже знакомы с подобным -- квадратные скобки. Они позволяют выбирать между несколькими символами, например `pattern:gr[ae]y` найдёт `match:gray`, либо `match:grey`.
2222

23-
Square brackets allow only characters or character sets. Alternation allows any expressions. A regexp `pattern:A|B|C` means one of expressions `A`, `B` or `C`.
23+
Квадратные скобки работают только с символами или наборами символов. Альтернация работает с любыми выражениями. Регулярное выражение `pattern:A|B|C` обозначает поиск одного из выражений: `A`, `B` или `C`.
2424

25-
For instance:
25+
Например:
2626

27-
- `pattern:gr(a|e)y` means exactly the same as `pattern:gr[ae]y`.
28-
- `pattern:gra|ey` means `match:gra` or `match:ey`.
27+
- `pattern:gr(a|e)y` означает точно то же, что и `pattern:gr[ae]y`.
28+
- `pattern:gra|ey` означает `match:gra` или `match:ey`.
2929

30-
To separate a part of the pattern for alternation we usually enclose it in parentheses, like this: `pattern:before(XXX|YYY)after`.
30+
Для отделения части паттерна с альтернацией мы обычно заключаем её в скобки, как здесь: `pattern:before(XXX|YYY)after`.
3131

32-
## Regexp for time
32+
## Регулярное выражение для времени
3333

34-
In previous chapters there was a task to build a regexp for searching time in the form `hh:mm`, for instance `12:00`. But a simple `pattern:\d\d:\d\d` is too vague. It accepts `25:99` as the time (as 99 seconds match the pattern).
34+
В предыдущих главах было задание написать регулярное выражение для поиска времени в формате `чч:мм`, например `12:00`. Но паттерн `pattern:\d\d:\d\d` слишком неопределённый. Он принимает `25:99` за время (99 секунд подходят под паттерн, но так не должно быть).
3535

36-
How can we make a better one?
36+
Как сделать лучшее выражение?
3737

38-
We can apply more careful matching. First, the hours:
38+
Мы можем применить более тщательное сравнение. Во-первых, часы:
3939

40-
- If the first digit is `0` or `1`, then the next digit can by anything.
41-
- Or, if the first digit is `2`, then the next must be `pattern:[0-3]`.
40+
- Если первая цифра `0` или `1`, тогда следующая цифра может быть любой.
41+
- Или если первая цифра `2`, тогда следующая должна быть `pattern:[0-3]`.
4242

43-
As a regexp: `pattern:[01]\d|2[0-3]`.
43+
В виде регулярного выражения: `pattern:[01]\d|2[0-3]`.
4444

45-
Next, the minutes must be from `0` to `59`. In the regexp language that means `pattern:[0-5]\d`: the first digit `0-5`, and then any digit.
45+
Затем, минуты должны быть от `0` до `59`. На языке регулярных выражений это означает `pattern:[0-5]\d`: первая цифра `0-5`, а за ней любая.
4646

47-
Let's glue them together into the pattern: `pattern:[01]\d|2[0-3]:[0-5]\d`.
47+
Давайте соединим их в одно выражение: `pattern:[01]\d|2[0-3]:[0-5]\d`.
4848

49-
We're almost done, but there's a problem. The alternation `pattern:|` now happens to be between `pattern:[01]\d` and `pattern:2[0-3]:[0-5]\d`.
49+
Почти готово, но есть проблема. Сейчас альтернация `pattern:|` выбирает между `pattern:[01]\d` и `pattern:2[0-3]:[0-5]\d`.
5050

51-
That's wrong, as it should be applied only to hours `[01]\d` OR `2[0-3]`. That's a common mistake when starting to work with regular expressions.
51+
Это неправильно, так как она должна примениться только к часам `[01]\d` ИЛИ `2[0-3]`. Это частая ошибка в начале работы с регулярными выражениями.
5252

53-
The correct variant:
53+
Правильный вариант:
5454

5555
```js run
5656
let reg = /([01]\d|2[0-3]):[0-5]\d/g;

0 commit comments

Comments
 (0)