Skip to content

Commit fd901d2

Browse files
Update article.md
1 parent 2e24134 commit fd901d2

1 file changed

Lines changed: 62 additions & 62 deletions

File tree

  • 9-regular-expressions/14-regexp-lookahead-lookbehind
Lines changed: 62 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,134 +1,134 @@
1-
# Lookahead and lookbehind
1+
# Перегляд уперед та назад
22

3-
Sometimes we need to find only those matches for a pattern that are followed or preceded by another pattern.
3+
Іноді, нам потрібно знайти тільки такі співпадіння з шаблоном, за якими слідує, або яким передує інший шаблон.
44

5-
There's a special syntax for that, called "lookahead" and "lookbehind", together referred to as "lookaround".
5+
Для цього існують спеціальні синтаксичні конструкції, котрі називається "перегляд уперед" та "перегляд назад".
66

7-
For the start, let's find the price from the string like `subject:1 turkey costs 30€`. That is: a number, followed by `subject:€` sign.
7+
Для початку, давайте знайдемо ціну у рядку `subject:1 індичка коштує 30€`. Маємо: число, за яким йде символ `subject:€`.
88

9-
## Lookahead
9+
## Перегляд уперед
1010

11-
The syntax is: `pattern:X(?=Y)`, it means "look for `pattern:X`, but match only if followed by `pattern:Y`". There may be any pattern instead of `pattern:X` and `pattern:Y`.
11+
Синтаксис виглядає наступнм чином: `pattern:X(?=Y)`, це означає "шукай `pattern:X`, але вважай його співпадінням, тільки якщо за ним слідує `pattern:Y`". Замість `pattern:X` та `pattern:Y` можуть бути будь-які інші шаблони.
1212

13-
For an integer number followed by `subject:€`, the regexp will be `pattern:\d+(?=€)`:
13+
Для цілого числа, за яким слідує `subject:€`, регулярний вираз виглядатиме наступним чином `pattern:\d+(?=€)`:
1414

1515
```js run
16-
let str = "1 turkey costs 30€";
16+
let str = "1 індичка коштує 30€";
1717

18-
alert( str.match(/\d+(?=€)/) ); // 30, the number 1 is ignored, as it's not followed by
18+
alert( str.match(/\d+(?=€)/) ); // 30, число 1 ігнорується, оскільки після нього не стоїть символ
1919
```
2020

21-
Please note: the lookahead is merely a test, the contents of the parentheses `pattern:(?=...)` is not included in the result `match:30`.
21+
Зверніть увагу: Перегляд уперед це свого роду тест, вміст в дужках `pattern:(?=...)` не входить до відображуваного регулярним виразом співпадіння `match:30`.
2222

23-
When we look for `pattern:X(?=Y)`, the regular expression engine finds `pattern:X` and then checks if there's `pattern:Y` immediately after it. If it's not so, then the potential match is skipped, and the search continues.
23+
Коли ми шукаємо `pattern:X(?=Y)`, регулярний вираз знаходить `pattern:X` і далі перевіряє наявність `pattern:Y` одразу після нього. Якщо це не так, тоді потенційне співпадіння пропускається і регулярний вираз продовжує пошук.
2424

25-
More complex tests are possible, e.g. `pattern:X(?=Y)(?=Z)` means:
25+
Можливі і більш складні тести, наприклад `pattern:X(?=Y)(?=Z)` означає:
2626

27-
1. Find `pattern:X`.
28-
2. Check if `pattern:Y` is immediately after `pattern:X` (skip if isn't).
29-
3. Check if `pattern:Z` is also immediately after `pattern:X` (skip if isn't).
30-
4. If both tests passed, then the `pattern:X` is a match, otherwise continue searching.
27+
1. Знайди `pattern:X`.
28+
2. Перевір, чи `pattern:Y` йде одразу після `pattern:X` (пропускай, якщо це не так).
29+
3. Перевір, чи `pattern:Z` також йде одразу пысля `pattern:X` (пропускай, якщо це не так).
30+
4. Якщо обидва тести пройдено, тоді `pattern:X` відповідає умовам пошуку, в інщому випадку - продовжуй пошук.
3131

32-
In other words, such pattern means that we're looking for `pattern:X` followed by `pattern:Y` and `pattern:Z` at the same time.
32+
Інакше кажучи, такий шаблон означає, що ми шукаємо на `pattern:X` за яким одночасно слідують `pattern:Y` та `pattern:Z`.
3333

34-
That's only possible if patterns `pattern:Y` and `pattern:Z` aren't mutually exclusive.
34+
Це можливо тільки за умови, якщо шаблон `pattern:Y` та `pattern:Z` не взаємовиключні.
3535

36-
For example, `pattern:\d+(?=\s)(?=.*30)` looks for `pattern:\d+` that is followed by a space `pattern:(?=\s)`, and there's `30` somewhere after it `pattern:(?=.*30)`:
36+
До прикладу, `pattern:\d+(?=\s)(?=.*30)` шукає на `pattern:\d+` за яким йде пробільний символ `pattern:(?=\s)`, а також `30` десь після нього `pattern:(?=.*30)`:
3737

3838
```js run
39-
let str = "1 turkey costs 30€";
39+
let str = "1 індичка коштує 30€";
4040

4141
alert( str.match(/\d+(?=\s)(?=.*30)/) ); // 1
4242
```
4343

44-
In our string that exactly matches the number `1`.
44+
В нашому рядку цим параметрам повністю відповідає число `1`.
4545

46-
## Negative lookahead
46+
## Негативний перегляд уперед
4747

48-
Let's say that we want a quantity instead, not a price from the same string. That's a number `pattern:\d+`, NOT followed by `subject:€`.
48+
Скажімо, ми хочем знайти кількість, а не ціну в тому самому рядку. Тобто, шукаємо число `pattern:\d+`, за якийм НЕ слідує `subject:€`.
4949

50-
For that, a negative lookahead can be applied.
50+
В такому випадку, доречним буде використання негативного перегляду уперед.
5151

52-
The syntax is: `pattern:X(?!Y)`, it means "search `pattern:X`, but only if not followed by `pattern:Y`".
52+
Синатксис виглядає наступним чином: `pattern:X(?!Y)`, і означає "шукай `pattern:X`, але за умови, що після нього не йде `pattern:Y`".
5353

5454
```js run
55-
let str = "2 turkeys cost 60€";
55+
let str = "2 індички коштують 60€";
5656

57-
alert( str.match(/\d+\b(?!€)/g) ); // 2 (the price is not matched)
57+
alert( str.match(/\d+\b(?!€)/g) ); // 2 (ціна не відповідає вимогам шаблону і не відображається в результаті)
5858
```
5959

60-
## Lookbehind
60+
## Перегляд назад
6161

62-
```warn header="Lookbehind browser compatibility"
63-
Please Note: Lookbehind is not supported in non-V8 browsers, such as Safari, Internet Explorer.
62+
```warn header="Сумісність браузерів з переглядом назад"
63+
Зверніть увагу: Перегляд назад не підтримується в браузерах з відміннимим від V8 двигунами, зокрема Safari, Internet Explorer.
6464
```
6565

66-
Lookahead allows to add a condition for "what follows".
66+
Перегляд уперед дозволяє додати умову на кшталт "те, що слідує після".
6767

68-
Lookbehind is similar, but it looks behind. That is, it allows to match a pattern only if there's something before it.
68+
Перегляд назад подібний, але дивиться у зворотньому напрямку. Таким чином, він виводить результат, тільки якщо співпадає і шаблон і те, що йде до нього.
6969

70-
The syntax is:
71-
- Positive lookbehind: `pattern:(?<=Y)X`, matches `pattern:X`, but only if there's `pattern:Y` before it.
72-
- Negative lookbehind: `pattern:(?<!Y)X`, matches `pattern:X`, but only if there's no `pattern:Y` before it.
70+
Синтаксис наступний:
71+
- Позитивний перегляд назад: `pattern:(?<=Y)X`, співпадає з `pattern:X`, тільки за умови, якщо перед ним є `pattern:Y`.
72+
- Негативний перегляд назад: `pattern:(?<!Y)X`, співпадає `pattern:X`, тільки за умови, якщо перед ним немає `pattern:Y`.
7373

74-
For example, let's change the price to US dollars. The dollar sign is usually before the number, so to look for `$30` we'll use `pattern:(?<=\$)\d+` -- an amount preceded by `subject:$`:
74+
Наприклад, змінимо ціну з евро на американські долари. Знак долару зазвичай стоїть перед числом, тому, для пошуку `$30` ми використовуватимемо `pattern:(?<=\$)\d+` -- сума, перед якою є символ `subject:$`:
7575

7676
```js run
77-
let str = "1 turkey costs $30";
77+
let str = "1 індичка коштує $30";
7878

79-
// the dollar sign is escaped \$
80-
alert( str.match(/(?<=\$)\d+/) ); // 30 (skipped the sole number)
79+
// знак долара екрановано \$
80+
alert( str.match(/(?<=\$)\d+/) ); // 30 (число 1 пропущено через відсутність знаку долару перед ним)
8181
```
8282

83-
And, if we need the quantity -- a number, not preceded by `subject:$`, then we can use a negative lookbehind `pattern:(?<!\$)\d+`:
83+
Також, якщо нам потрібна кількість -- число, якому не передує `subject:$`, в такому випадку ми можемо використати негативний перегляд назад `pattern:(?<!\$)\d+`:
8484

8585
```js run
86-
let str = "2 turkeys cost $60";
86+
let str = "2 індички коштують $60";
8787

88-
alert( str.match(/(?<!\$)\b\d+/g) ); // 2 (the price is not matched)
88+
alert( str.match(/(?<!\$)\b\d+/g) ); // 2 (ціна не спвіпадає з умовами пошуку)
8989
```
9090

91-
## Capturing groups
91+
## Дужкові групи
9292

93-
Generally, the contents inside lookaround parentheses does not become a part of the result.
93+
Зазвичай, вміст в дужках перегляду вперед та назад не є частиною співпадіння.
9494

95-
E.g. in the pattern `pattern:\d+(?=€)`, the `pattern:€` sign doesn't get captured as a part of the match. That's natural: we look for a number `pattern:\d+`, while `pattern:(?=€)` is just a test that it should be followed by `subject:€`.
95+
Наприклад, у шаблоні `pattern:\d+(?=€)`, символ `pattern:€` не відображається при виведенні співпадінь. Це нормально: ми шукаємо на число `pattern:\d+`, тоді як `pattern:(?=€)` це лише перевірка на те, чи дійсно за ним йде символ `subject:€`.
9696

97-
But in some situations we might want to capture the lookaround expression as well, or a part of it. That's possible. Just wrap that part into additional parentheses.
97+
Але в деяких ситуаціях ми можемо поребувати виведення вмісту шаблону перегляду вперед та назад, або його частини. Це можливо. Просто огорніть потрібну частину в додаткові круглі дужки.
9898

99-
In the example below the currency sign `pattern:(€|kr)` is captured, along with the amount:
99+
В нижченаведеному прикладі знак валюти `pattern:(€|kr)` теж відображено у результаті, разом із сумою:
100100

101101
```js run
102-
let str = "1 turkey costs 30€";
103-
let regexp = /\d+(?=(€|kr))/; // extra parentheses around €|kr
102+
let str = "1 індичка коштує 30€";
103+
let regexp = /\d+(?=(€|kr))/; // додаткові круглі дужки навколо €|kr
104104

105105
alert( str.match(regexp) ); // 30, €
106106
```
107107

108-
And here's the same for lookbehind:
108+
І так само для перегляду назад:
109109

110110
```js run
111-
let str = "1 turkey costs $30";
111+
let str = "1 індичка коштує $30";
112112
let regexp = /(?<=(\$|£))\d+/;
113113

114114
alert( str.match(regexp) ); // 30, $
115115
```
116116

117-
## Summary
117+
## Підсумок
118118

119-
Lookahead and lookbehind (commonly referred to as "lookaround") are useful when we'd like to match something depending on the context before/after it.
119+
Перегляд вперед на назад корисні, коли нам потрібно знайти щось, залежно від контексту до чи після потрібного шаблону.
120120

121-
For simple regexps we can do the similar thing manually. That is: match everything, in any context, and then filter by context in the loop.
121+
Для простих регулярних виразів ми можемо виконати подібну задачу вручну. Тобто: відшукати всі спвіпадіння, у будь-якому контексті, а потім відфільтрувати їх за контекстом за допомогою циклу.
122122

123-
Remember, `str.match` (without flag `pattern:g`) and `str.matchAll` (always) return matches as arrays with `index` property, so we know where exactly in the text it is, and can check the context.
123+
Пам'ятайте, `str.match` (без флажку `pattern:g`) і `str.matchAll` (всі) повертає співпадіння у вигляді масиву з властивістю `індекс`, тож ми точно знаємо де саме в тексті вони знаходяться і можемо перевірити контекст.
124124

125-
But generally lookaround is more convenient.
125+
Але загалом перегляд уперед і назад більш підходящі.
126126

127-
Lookaround types:
127+
Типи переглядів:
128128

129-
| Pattern | type | matches |
129+
| Шаблон | Тип | Співпадіння |
130130
|--------------------|------------------|---------|
131-
| `X(?=Y)` | Positive lookahead | `pattern:X` if followed by `pattern:Y` |
132-
| `X(?!Y)` | Negative lookahead | `pattern:X` if not followed by `pattern:Y` |
133-
| `(?<=Y)X` | Positive lookbehind | `pattern:X` if after `pattern:Y` |
134-
| `(?<!Y)X` | Negative lookbehind | `pattern:X` if not after `pattern:Y` |
131+
| `X(?=Y)` | Позитивний перегляд уперед | `pattern:X` якщо за ним йде `pattern:Y` |
132+
| `X(?!Y)` | Негативний перегляд уперед | `pattern:X` якщо за ним не йде `pattern:Y` |
133+
| `(?<=Y)X` | Позитивний перегляд назад | `pattern:X` якщо він йде після `pattern:Y` |
134+
| `(?<!Y)X` | Негативний перегляд назад | `pattern:X` якщо тільки він не йде після `pattern:Y` |

0 commit comments

Comments
 (0)