Skip to content

Capturing groups #441

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 25, 2023
Merged
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
16 changes: 8 additions & 8 deletions 9-regular-expressions/11-regexp-groups/01-test-mac/solution.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
A two-digit hex number is `pattern:[0-9a-f]{2}` (assuming the flag `pattern:i` is set).
Двоцифрове шістнадцяткове число можна записати як `pattern:[0-9a-f]{2}`(припустивши, що задано прапорець `pattern:i`).

We need that number `NN`, and then `:NN` repeated 5 times (more numbers);
Нам потрібно число `NN`, а за ним `:NN`, повторене 5 разів (більше чисел);

The regexp is: `pattern:[0-9a-f]{2}(:[0-9a-f]{2}){5}`
Регулярний вираз: `pattern:[0-9a-f]{2}(:[0-9a-f]{2}){5}`

Now let's show that the match should capture all the text: start at the beginning and end at the end. That's done by wrapping the pattern in `pattern:^...$`.
Тепер продемонструємо, що збіг має захоплювати весь текст: з самого початку до самого кінця. Робиться це через огортання виразу в `pattern:^...$`.

Finally:
В підсумку:

```js run
let regexp = /^[0-9a-f]{2}(:[0-9a-f]{2}){5}$/i;

alert( regexp.test('01:32:54:67:89:AB') ); // true

alert( regexp.test('0132546789AB') ); // false (no colons)
alert( regexp.test('0132546789AB') ); // false (без двокрапок)

alert( regexp.test('01:32:54:67:89') ); // false (5 numbers, need 6)
alert( regexp.test('01:32:54:67:89') ); // false (5 чисел, має бути 6)

alert( regexp.test('01:32:54:67:89:ZZ') ) // false (ZZ in the end)
alert( regexp.test('01:32:54:67:89:ZZ') ) // false (ZZ в кінці)
```
18 changes: 9 additions & 9 deletions 9-regular-expressions/11-regexp-groups/01-test-mac/task.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
# Check MAC-address
# Перевірити MAC-адресу

[MAC-address](https://en.wikipedia.org/wiki/MAC_address) of a network interface consists of 6 two-digit hex numbers separated by a colon.
[MAC-адреса](https://uk.wikipedia.org/wiki/MAC-адреса) мережевого інтерфейсу складається з 6 двоцифрових шістнадцяткових чисел, розділених двокрапкою.

For instance: `subject:'01:32:54:67:89:AB'`.
Наприклад: `subject:'01:32:54:67:89:AB'`.

Write a regexp that checks whether a string is MAC-address.
Напишіть регулярний вираз, який перевіряє, чи є рядок MAC-адресою.

Usage:
Приклад використання:
```js
let regexp = /your regexp/;
let regexp = /ваш регулярний вираз/;

alert( regexp.test('01:32:54:67:89:AB') ); // true

alert( regexp.test('0132546789AB') ); // false (no colons)
alert( regexp.test('0132546789AB') ); // false (без двокрапок)

alert( regexp.test('01:32:54:67:89') ); // false (5 numbers, must be 6)
alert( regexp.test('01:32:54:67:89') ); // false (5 чисел, має бути 6)

alert( regexp.test('01:32:54:67:89:ZZ') ) // false (ZZ at the end)
alert( regexp.test('01:32:54:67:89:ZZ') ) // false (ZZ в кінці)
```
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
A regexp to search 3-digit color `#abc`: `pattern:/#[a-f0-9]{3}/i`.
Регулярний вираз для пошуку тризначного коду кольору `#abc`: `pattern:/#[a-f0-9]{3}/i`.

We can add exactly 3 more optional hex digits. We don't need more or less. The color has either 3 or 6 digits.
Ми можемо додати рівно 3 додаткові шістнадцяткові цифри, не більше й не менше. Колір містить 3 або 6 цифр.

Let's use the quantifier `pattern:{1,2}` for that: we'll have `pattern:/#([a-f0-9]{3}){1,2}/i`.
Використаємо для цього квантифікатор `pattern:{1,2}`: отримаємо `pattern:/#([a-f0-9]{3}){1,2}/i`.

Here the pattern `pattern:[a-f0-9]{3}` is enclosed in parentheses to apply the quantifier `pattern:{1,2}`.
В цьому випадку, шаблон `pattern:[a-f0-9]{3}` оточений дужками для застосування квантифікатора `pattern:{1,2}`.

In action:
Код у дії:

```js run
let regexp = /#([a-f0-9]{3}){1,2}/gi;
Expand All @@ -16,7 +16,7 @@ let str = "color: #3f3; background-color: #AA00ef; and: #abcd";
alert( str.match(regexp) ); // #3f3 #AA00ef #abc
```

There's a minor problem here: the pattern found `match:#abc` in `subject:#abcd`. To prevent that we can add `pattern:\b` to the end:
Бачимо невелику проблему: вираз знайшов `match:#abc` в `subject:#abcd`. Для запобігання цьому, додамо в кінці `pattern:\b`:

```js run
let regexp = /#([a-f0-9]{3}){1,2}\b/gi;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# Find color in the format #abc or #abcdef
# Знайти колір у форматі #abc або #abcdef

Write a RegExp that matches colors in the format `#abc` or `#abcdef`. That is: `#` followed by 3 or 6 hexadecimal digits.
Напишіть регулярний вираз, що знаходить збіг по кольорам у форматі `#abc` або `#abcdef`. Формула є наступною: `#`, за яким знаходяться 3 або 6 шістнадцяткових цифр.

Usage example:
Приклад використання:
```js
let regexp = /your regexp/g;
let regexp = /ваш регулярний вираз/g;

let str = "color: #3f3; background-color: #AA00ef; and: #abcd";

alert( str.match(regexp) ); // #3f3 #AA00ef
```

P.S. This should be exactly 3 or 6 hex digits. Values with 4 digits, such as `#abcd`, should not match.
P.S. Має бути саме 3 або 6 шістнадцяткових цифр. Значення з 4 цифрами, такі як `#abcd`, не мають рахуватись за збіг.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
A positive number with an optional decimal part is: `pattern:\d+(\.\d+)?`.
Додатне число з необов’язковою десятковою частиною: `pattern:\d+(\.\d+)?`.

Let's add the optional `pattern:-` in the beginning:
Додамо необов’язковий `pattern:-` на початку:

```js run
let regexp = /-?\d+(\.\d+)?/g;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Find all numbers
# Знайти всі числа

Write a regexp that looks for all decimal numbers including integer ones, with the floating point and negative ones.
Напишіть регулярний вираз, який шукатиме всі десяткові числа, включно з числами цілими, з плаваючою комою та від’ємними.

An example of use:
Приклад використання:

```js
let regexp = /your regexp/g;
let regexp = /ваш регулярний вираз/g;

let str = "-1.5 0 2 -123.4.";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,44 +1,44 @@
A regexp for a number is: `pattern:-?\d+(\.\d+)?`. We created it in the previous task.
Регулярний вираз для числа є наступним: `pattern:-?\d+(\.\d+)?`. Його ми створили в рамках попередньої задачі.

An operator is `pattern:[-+*/]`. The hyphen `pattern:-` goes first in the square brackets, because in the middle it would mean a character range, while we just want a character `-`.
Оператором слугуватиме `pattern:[-+*/]`. Дефіс `pattern:-` стоїть першим в квадратних дужках, бо позиція посередині означає діапазон знаків, тоді як нам потрібен лише `-`.

The slash `/` should be escaped inside a JavaScript regexp `pattern:/.../`, we'll do that later.
Символ `/` має бути екранованим всередині регулярного виразу JavaScript `pattern:/.../`, зробимо це потім.

We need a number, an operator, and then another number. And optional spaces between them.
Нам потрібне число, оператор, тоді ще одне число. Та можливі пробіли між ними.

The full regular expression: `pattern:-?\d+(\.\d+)?\s*[-+*/]\s*-?\d+(\.\d+)?`.
Повний регулярний вираз: `pattern:-?\d+(\.\d+)?\s*[-+*/]\s*-?\d+(\.\d+)?`.

It has 3 parts, with `pattern:\s*` between them:
1. `pattern:-?\d+(\.\d+)?` - the first number,
1. `pattern:[-+*/]` - the operator,
1. `pattern:-?\d+(\.\d+)?` - the second number.
Він містить 3 частини, з `pattern:\s*` між ними:
1. `pattern:-?\d+(\.\d+)?` - перше число,
1. `pattern:[-+*/]` - оператор,
1. `pattern:-?\d+(\.\d+)?` - друге число.

To make each of these parts a separate element of the result array, let's enclose them in parentheses: `pattern:(-?\d+(\.\d+)?)\s*([-+*/])\s*(-?\d+(\.\d+)?)`.
Аби зробити кожну з цих частин окремим елементом масиву результатів, помістимо їх в круглі дужки: `pattern:(-?\d+(\.\d+)?)\s*([-+*/])\s*(-?\d+(\.\d+)?)`.

In action:
Код у дії:

```js run
let regexp = /(-?\d+(\.\d+)?)\s*([-+*\/])\s*(-?\d+(\.\d+)?)/;

alert( "1.2 + 12".match(regexp) );
```

The result includes:
Розглянемо результат:

- `result[0] == "1.2 + 12"` (full match)
- `result[1] == "1.2"` (first group `(-?\d+(\.\d+)?)` -- the first number, including the decimal part)
- `result[2] == ".2"` (second group`(\.\d+)?` -- the first decimal part)
- `result[3] == "+"` (third group `([-+*\/])` -- the operator)
- `result[4] == "12"` (forth group `(-?\d+(\.\d+)?)` -- the second number)
- `result[5] == undefined` (fifth group `(\.\d+)?` -- the last decimal part is absent, so it's undefined)
- `result[0] == "1.2 + 12"` (повний збіг)
- `result[1] == "1.2"` (перша група `(-?\d+(\.\d+)?)` -- перше число, включаючи десяткову частину)
- `result[2] == ".2"` (друга група `(\.\d+)?` -- перша десяткова частина)
- `result[3] == "+"` (третя група `([-+*\/])` -- оператор)
- `result[4] == "12"` (четверта група `(-?\d+(\.\d+)?)` -- друге число)
- `result[5] == undefined` (п’ята група `(\.\d+)?` -- остання десяткова частина відсутня, тому вона undefined)

We only want the numbers and the operator, without the full match or the decimal parts, so let's "clean" the result a bit.
Нам потрібні лише числа та оператор, без повного збігу чи десяткових частин, тож проведемо невелику "чистку" результату.

The full match (the arrays first item) can be removed by shifting the array `result.shift()`.
Повний збіг (перший елемент масиву) можна прибрати методом масиву `result.shift()`.

Groups that contain decimal parts (number 2 and 4) `pattern:(.\d+)` can be excluded by adding `pattern:?:` to the beginning: `pattern:(?:\.\d+)?`.
Групи 2 та 5, що містять десяткові частини `pattern:(.\d+)`, можна оминути, додавши `pattern:?:` на початку: `pattern:(?:\.\d+)?`.

The final solution:
Кінцевий варіант:

```js run
function parse(expr) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
# Parse an expression
# Розберіть вираз

An arithmetical expression consists of 2 numbers and an operator between them, for instance:
Арифметичний вираз складається з двох чисел та оператору між ними, наприклад:

- `1 + 2`
- `1.2 * 3.4`
- `-3 / -6`
- `-2 - 2`

The operator is one of: `"+"`, `"-"`, `"*"` or `"/"`.
Оператором може бути: `"+"`, `"-"`, `"*"` або `"/"`.

There may be extra spaces at the beginning, at the end or between the parts.
Додаткові пробіли можуть бути на початку, в кінці чи всередині виразу.

Create a function `parse(expr)` that takes an expression and returns an array of 3 items:
Напишіть функцію `parse(expr)`, яка приймає вираз та повертає масив з 3-ьох елементів:

1. The first number.
2. The operator.
3. The second number.
1. Перше число.
2. Оператор.
3. Друге число.

For example:
Наприклад:

```js
let [a, op, b] = parse("1.2 * 3.4");
Expand Down
Loading