Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Положительное число с необязательным присутствием десятичной части (из прошлой задачи): `pattern:\d+(\.\d+)?`.
Положительное число с необязательным присутствием десятичной части: `pattern:\d+(\.\d+)?`.

Добавим необязательный минус `pattern:-?` в начало:

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
Регулярное выражение для числа: `pattern:-?\d+(\.\d+)?`. Мы создали его в предыдущих задачах.
Регулярное выражение для числа: `pattern:-?\d+(\.\d+)?`. Мы создали его в предыдущей задаче.

Регулярное выражение для оператора `pattern:[-+*/]`. Дефис `pattern:-` стоит в начале квадратных скобок, потому что в середине этот символ будет означать диапазон, а нам нужен просто символ `-`.

Отметим, что косая черта должна быть экранирована внутри регулярного выражения JavaScript `pattern:/.../`.
Отметим, что косая черта должна быть экранирована внутри регулярного выражения JavaScript `pattern:/.../`, мы сделаем это позже.

Нам необходимо число, оператор и, затем, другие числа. Между ними могут быть необязательные пробелы.
Нам необходимо число, оператор и затем другое число. Между ними могут быть необязательные пробелы.

Полное выражение: `pattern:-?\d+(\.\d+)?\s*[-+*/]\s*-?\d+(\.\d+)?`.

Expand Down Expand Up @@ -54,3 +54,17 @@ function parse(expr) {

alert( parse("-1.23 * 3.45") ); // -1.23, *, 3.45
```

В качестве альтернативы исключению из запоминания `pattern:?:` мы могли бы использовать именованные группы следующим образом:

```js run
function parse(expr) {
let regexp = /(?<a>-?\d+(?:\.\d+)?)\s*(?<operator>[-+*\/])\s*(?<b>-?\d+(?:\.\d+)?)/;

let result = expr.match(regexp);

return [result.groups.a, result.groups.operator, result.groups.b];
}

alert( parse("-1.23 * 3.45") ); // -1.23, *, 3.45;
```
14 changes: 7 additions & 7 deletions 9-regular-expressions/11-regexp-groups/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
У такого выделения есть два эффекта:

1. Позволяет поместить часть совпадения в отдельный массив.
2. Если установить квантификатор после скобок, то он будет применяться ко всему содержимому скобки, а не к одному символу.
2. Если установить квантификатор после скобок, то он будет применяться ко всему содержимому группы, а не к одному символу.

## Примеры

Expand Down Expand Up @@ -209,7 +209,7 @@ alert(results[0]); // <h1>,h1 (первый тег)
alert(results[1]); // <h2>,h2 (второй тег)
```

Как видите, первое отличие - очень важное, это демонстрирует строка `(*)`. Мы не можем получить совпадение как `results[0]`, так как этот объект не является псевдомассивом. Его можно превратить в настоящий массив при помощи `Array.from`. Более подробно о псевдомассивах и перебираемых объектов мы говорили в главе <info:iterable>.
Как видите, первое отличие - очень важное, это демонстрирует строка `(*)`. Мы не можем получить совпадение как `results[0]`, так как этот объект не является псевдомассивом. Его можно превратить в настоящий массив при помощи `Array.from`. Более подробно о псевдомассивах и перебираемых объектах мы говорили в главе <info:iterable>.

В явном преобразовании через `Array.from` нет необходимости, если мы перебираем результаты в цикле, вот так:

Expand Down Expand Up @@ -254,7 +254,7 @@ alert( tag1.input ); // <h1> <h2>

## Именованные группы

Запоминать группы по номерам не очень удобно. Для простых шаблонов это допустимо, но в сложных регулярных выражениях считать скобки затруднительно. Гораздо лучше - давать скобкам имена.
Запоминать группы по номерам не очень удобно. Для простых шаблонов это допустимо, но в сложных регулярных выражениях считать скобки затруднительно. Гораздо лучше - давать группам имена.

Это делается добавлением `pattern:?<name>` непосредственно после открытия скобки.

Expand Down Expand Up @@ -308,7 +308,7 @@ let regexp = /(\w+) (\w+)/;
alert( str.replace(regexp, '$2, $1') ); // Bull, John
```

Для именованных скобок ссылка будет выглядеть как `pattern:$<имя>`.
Для именованных групп ссылка будет выглядеть как `pattern:$<имя>`.

Например, заменим даты в формате "год-месяц-день" на "день.месяц.год":

Expand Down Expand Up @@ -350,7 +350,7 @@ alert( result.length ); // 2 (больше в массиве элементов

## Итого

Круглые скобки группируют вместе часть регулярного выражения, так что квантификатор применяется к ним в целом.
Круглые скобки группируют вместе часть регулярного выражения, так что квантификатор применяется к ней в целом.

Скобочные группы нумеруются слева направо. Также им можно дать имя с помощью `pattern:(?<name>...)`.

Expand All @@ -359,8 +359,8 @@ alert( result.length ); // 2 (больше в массиве элементов
- Метод `str.match` возвращает скобочные группы только без флага `pattern:g`.
- Метод `str.matchAll` возвращает скобочные группы всегда.

Если скобка не имеет имени, то содержимое группы будет по своему номеру в массиве-результате, если имеет, то также в свойстве `groups`.
Если скобочная группа не имеет имени, то её содержимое будет по своему номеру в массиве-результате, а если имеет, то также в свойстве `groups`.

Содержимое скобочной группы можно также использовать при замене `str.replace(regexp, replacement)`: по номеру `$n` или по имени `$<имя>`.

Можно исключить скобочную группу из запоминания, добавив в её начало `pattern:?:`. Это используется, если необходимо применить квантификатор ко всей группе, но не запоминать их содержимое в отдельном элементе массива-результата. Также мы не можем ссылаться на такие скобки в строке замены.
Можно исключить скобочную группу из запоминания, добавив в её начало `pattern:?:`. Это используется, если необходимо применить квантификатор ко всей группе, но не запоминать её содержимое в отдельном элементе массива-результата. Также мы не можем ссылаться на такую группу в строке замены.