Skip to content
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

Quantifiers +, *, ? and {n} #420

Merged
Merged
Changes from 1 commit
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
105 changes: 52 additions & 53 deletions 9-regular-expressions/09-regexp-quantifiers/article.md
Original file line number Diff line number Diff line change
@@ -1,142 +1,141 @@
# Quantifiers +, *, ? and {n}
# Квантифікатори +, *, ? та {n}

Let's say we have a string like `+7(903)-123-45-67` and want to find all numbers in it. But unlike before, we are interested not in single digits, but full numbers: `7, 903, 123, 45, 67`.
Припустимо, у нас є рядок `+38(067)-123-45-67` і нам потрібно знайти всі числа в ньому. Але цього разу, на відміну від попередніх, нас цікавлять не поодинокі цифри, а саме числа : `38, 067, 123, 45, 67`.

A number is a sequence of 1 or more digits `pattern:\d`. To mark how many we need, we can append a *quantifier*.
Число це послідовність з 1, або більше цифр `pattern:\d` і щоб позначити потрібну нам кількість, ми можемо застосувати *квантифікатор*.

## Quantity {n}
## Кількість {n}

The simplest quantifier is a number in curly braces: `pattern:{n}`.
Найпростішим квантифікатором є число у фігурних дужках: `pattern:{n}`.

A quantifier is appended to a character (or a character class, or a `[...]` set etc) and specifies how many we need.
Квантифікатор додається до символу(або класу символів, набору `[...]`, тощо) і позначає яка їх кількість нам потрібна.
Існує декілька способів використання квантифікатора, розглянемо на прикладах:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Текст перекладу має бути на тих самих рядках як і в оригіналі. Це потрібно для того, щоб у майбутньому легшебуло синхронізувати зміни. Зробіт, будь ласка, цей рядок 13-им :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done :)


It has a few advanced forms, let's see examples:
Точна кількість: `pattern:{5}`
: `pattern:\d{5}` означає точно 5 цифр, так само як і `pattern:\d\d\d\d\d`.

The exact count: `pattern:{5}`
: `pattern:\d{5}` denotes exactly 5 digits, the same as `pattern:\d\d\d\d\d`.

The example below looks for a 5-digit number:
Нижченаведений приклад шукатиме число, яке складається з 5-ти цифр:

```js run
alert( "I'm 12345 years old".match(/\d{5}/) ); // "12345"
alert( "Мені 12345 років".match(/\d{5}/) ); // "12345"
```

We can add `\b` to exclude longer numbers: `pattern:\b\d{5}\b`.
Ми могли б додати `\b` і таким чином вилучити з пошуку числа довші за наш шаблон: `pattern:\b\d{5}\b`.

The range: `pattern:{3,5}`, match 3-5 times
: To find numbers from 3 to 5 digits we can put the limits into curly braces: `pattern:\d{3,5}`
Діапазон: `pattern:{3,5}`, від 3 до 5
: Щоб знайти числа, які складаються з мінімум 3 і максимум 5 чисел, ми можемо вказати потрібні обмеження у фігурних дужках: `pattern:\d{3,5}`

```js run
alert( "I'm not 12, but 1234 years old".match(/\d{3,5}/) ); // "1234"
alert( "Мені не 12 років, а 1234".match(/\d{3,5}/) ); // "1234"
```

We can omit the upper limit.
Ми можемо не вказувати верхню межу.

Then a regexp `pattern:\d{3,}` looks for sequences of digits of length `3` or more:
В такому випадку, регулярний вираз `pattern:\d{3,}` шукатиме послідовність цифр довжиною від `3` і/або більше:

```js run
alert( "I'm not 12, but 345678 years old".match(/\d{3,}/) ); // "345678"
alert( "Мені не 12, а 345678 років".match(/\d{3,}/) ); // "345678"
```

Let's return to the string `+7(903)-123-45-67`.
Давайте повернемось до рядка `+38(067)-123-45-67`.

A number is a sequence of one or more digits in a row. So the regexp is `pattern:\d{1,}`:
Число це послідовність з однієї або більше цифр підряд. Таким чином, регулярний вираз виглядатиме `pattern:\d{1,}`:

```js run
let str = "+7(903)-123-45-67";
let str = "+38(067)-123-45-67";

let numbers = str.match(/\d{1,}/g);

alert(numbers); // 7,903,123,45,67
alert(numbers); // 38,067,123,45,67
```

## Shorthands
## Скорочення

There are shorthands for most used quantifiers:
Існують способи скорочено записати більшу частину часто вживаних квантифікаторів:

`pattern:+`
: Means "one or more", the same as `pattern:{1,}`.
: Означає "один, або більше", так само як і `pattern:{1,}`.

For instance, `pattern:\d+` looks for numbers:
До прикладу, `pattern:\d+` шукає числа, які складаються з однієї, або більше цифр:

```js run
let str = "+7(903)-123-45-67";
let str = "+38(067)-123-45-67";

alert( str.match(/\d+/g) ); // 7,903,123,45,67
alert( str.match(/\d+/g) ); // 38,067,123,45,67
```

`pattern:?`
: Means "zero or one", the same as `pattern:{0,1}`. In other words, it makes the symbol optional.
: Означає "нуль, або один", так само як і `pattern:{0,1}`. Інакше кажучи, в такий спосіб ми робимо символ необов'язковим.

For instance, the pattern `pattern:ou?r` looks for `match:o` followed by zero or one `match:u`, and then `match:r`.
До прикладу, шаблон `pattern:ou?r` шукатиме літеру `match:o` після якої, можливо, йтиме літера `match:u`, і потім літера `match:r`.

So, `pattern:colou?r` finds both `match:color` and `match:colour`:
І таким чином, `pattern:colou?r` знайде обидва слова `match:color` та `match:colour`:

```js run
let str = "Should I write color or colour?";
let str = "Англійською слово колір пишеться як color чи colour?";

alert( str.match(/colou?r/g) ); // color, colour
```

`pattern:*`
: Means "zero or more", the same as `pattern:{0,}`. That is, the character may repeat any times or be absent.
: Означає "нуль, або більше", так само, як і `pattern:{0,}`. Це означає, що символ може бути відсутнім, або повторюватись безліч разів.

For example, `pattern:\d0*` looks for a digit followed by any number of zeroes (may be many or none):
До прикладу, `pattern:\d0*` шукає цифру, після якої йде будь-яка кількість нулів (може бути багато, або жодного):

```js run
alert( "100 10 1".match(/\d0*/g) ); // 100, 10, 1
```

Compare it with `pattern:+` (one or more):
Порівняйте з `pattern:+` (один, або більше):

```js run
alert( "100 10 1".match(/\d0+/g) ); // 100, 10
// 1 not matched, as 0+ requires at least one zero
// Регулярний вираз не знайшов 1, оскільки 0+ вимагає наявності щонайменше одного нуля
```

## More examples
## Більше прикладів

Quantifiers are used very often. They serve as the main "building block" of complex regular expressions, so let's see more examples.
Квантифікатори використовують дуже часто. Вони основні "будівельні блоки" складних регулярних виразів, тож розглянемо ще декілька прикладів.
MrsMelnychenko marked this conversation as resolved.
Show resolved Hide resolved

**Regexp for decimal fractions (a number with a floating point): `pattern:\d+\.\d+`**
**Регулярний вираз для десяткових дробів (чисел з плаваючою комою): `pattern:\d+\.\d+`**

In action:
В дії:
```js run
alert( "0 1 12.345 7890".match(/\d+\.\d+/g) ); // 12.345
```

**Regexp for an "opening HTML-tag without attributes", such as `<span>` or `<p>`.**
**Регулярний вираз для "відкриваючого HTML-тегу без атрибутів", наприклад, `<span>`, або `<p>`.**

1. The simplest one: `pattern:/<[a-z]+>/i`
1. Найпростіший варіант: `pattern:/<[a-z]+>/i`

```js run
alert( "<body> ... </body>".match(/<[a-z]+>/gi) ); // <body>
```

The regexp looks for character `pattern:'<'` followed by one or more Latin letters, and then `pattern:'>'`.
Регулярний вираз шукає символ `pattern:'<'` після якого йдуть одна, або більше літер латиницею, а потім `pattern:'>'`.

2. Improved: `pattern:/<[a-z][a-z0-9]*>/i`
2. Покращений варіант: `pattern:/<[a-z][a-z0-9]*>/i`

According to the standard, HTML tag name may have a digit at any position except the first one, like `<h1>`.
Згідно стандарту, назва HTML-тегу може містити в собі і цифру на будь-якій позиції окрім першої, як наприклад `<h1>`.

```js run
alert( "<h1>Hi!</h1>".match(/<[a-z][a-z0-9]*>/gi) ); // <h1>
```

**Regexp "opening or closing HTML-tag without attributes": `pattern:/<\/?[a-z][a-z0-9]*>/i`**
**Регулярний вираз "відкриваючого, або закриваючого HTML-тегу без атрибутів": `pattern:/<\/?[a-z][a-z0-9]*>/i`**

We added an optional slash `pattern:/?` near the beginning of the pattern. Had to escape it with a backslash, otherwise JavaScript would think it is the pattern end.
Ми додали необов'язковий слеш `pattern:/?` на початку шаблону і для того, щоб JavaScript не сприйняв його як кінець регулярного виразу, нам довелось його екранувати.

```js run
alert( "<h1>Hi!</h1>".match(/<\/?[a-z][a-z0-9]*>/gi) ); // <h1>, </h1>
```

```smart header="To make a regexp more precise, we often need make it more complex"
We can see one common rule in these examples: the more precise is the regular expression -- the longer and more complex it is.
```smart header="Щоб зробити регулярний вираз більш точний, нам часто доводиться його ускладнювати"
dolgachio marked this conversation as resolved.
Show resolved Hide resolved
На прикладах ми побачили, що більш точним є регулярний вираз, тим довшим і складнішим є його реалізація.

For instance, for HTML tags we could use a simpler regexp: `pattern:<\w+>`. But as HTML has stricter restrictions for a tag name, `pattern:<[a-z][a-z0-9]*>` is more reliable.
До прикладу, для HTML-тегів без атрибутів ми могли б використати простіший регулярний вираз: `pattern:<\w+>`. Але так як HTML має більш жорсткі вимоги до назв тегів, то шаблон `pattern:<[a-z][a-z0-9]*>` буде більш точним.

Can we use `pattern:<\w+>` or we need `pattern:<[a-z][a-z0-9]*>`?
Чи можемо ми використовувати `pattern:<\w+>` чи краще писати `pattern:<[a-z][a-z0-9]*>`?

In real life both variants are acceptable. Depends on how tolerant we can be to "extra" matches and whether it's difficult or not to remove them from the result by other means.
в реальному життя обидва варіанти мають право на існування. Все залежить від того, чи готові ми допустити "зайві" співпадіння з нашим регулярний виразом і наскілльки важко, або легко буде відфільтрувати їх і отримати перелік потрібних нам співпадінь.
dolgachio marked this conversation as resolved.
Show resolved Hide resolved
```