Skip to content

Lookahead and lookbehind #439

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 11 commits into from
Mar 12, 2023
Merged
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@

The regexp for an integer number is `pattern:\d+`.
Регулярний вираз для цілого числа `pattern:\d+`.

We can exclude negatives by prepending it with the negative lookbehind: `pattern:(?<!-)\d+`.
Ми можемо виключити від'ємні числа попередньо написавши регулярний вираз для негативної зворотньої перевірки: `pattern:(?<!-)\d+`.

Although, if we try it now, we may notice one more "extra" result:
Хоча, випробувавши його, ми побачимо одне зайве співпадіння:

```js run
let regexp = /(?<!-)\d+/g;
Expand All @@ -13,11 +13,11 @@ let str = "0 12 -5 123 -18";
console.log( str.match(regexp) ); // 0, 12, 123, *!*8*/!*
```

As you can see, it matches `match:8`, from `subject:-18`. To exclude it, we need to ensure that the regexp starts matching a number not from the middle of another (non-matching) number.
Як ви бачите, шаблон знаходить `match:8`, у `subject:-18`. Щоб виключити і його, нам необхідно переконатись, що регулярний вираз починає пошук не з середини іншого числа, яке не підходить.

We can do it by specifying another negative lookbehind: `pattern:(?<!-)(?<!\d)\d+`. Now `pattern:(?<!\d)` ensures that a match does not start after another digit, just what we need.
Ми можемо це реалізувати вказавши додатковий вираз для негативної зворотньої перевірки: `pattern:(?<!-)(?<!\d)\d+`. Зараз `pattern:(?<!\d)` перевіряє, щоб пошук не починався одразу після іншого числа, як нам і було потрібно.

We can also join them into a single lookbehind here:
Ми можемо об'єднати їх в один таким чином:

```js run
let regexp = /(?<![-\d])\d+/g;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Find non-negative integers
# Знайдіть цілі невід'ємні числа

There's a string of integer numbers.
Є рядок з цілих чисел.

Create a regexp that looks for only non-negative ones (zero is allowed).
Напишіть регулярний вираз, який знаходить тільки цілі невід'ємні числа (нуль допускається).

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

let str = "0 12 -5 123 -18";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
In order to insert after the `<body>` tag, we must first find it. We can use the regular expression pattern `pattern:<body.*?>` for that.
Щоб вставити після тегу `<body>` , нам потрібно спершу його знайти. Ми можемо використати для цього регулярний вираз `pattern:<body.*?>`.

In this task we don't need to modify the `<body>` tag. We only need to add the text after it.
в цьому завданні нам не потрібно змінювати тег `<body>`. Нам потрібно тільки додати текст після нього.

Here's how we can do it:
Ось таким чином ми можемо це зробити:

```js run
let str = '...<body style="...">...';
str = str.replace(/<body.*?>/, '$&<h1>Hello</h1>');
str = str.replace(/<body.*?>/, '$&<h1>Привіт</h1>');

alert(str); // ...<body style="..."><h1>Hello</h1>...
alert(str); // ...<body style="..."><h1>Привіт</h1>...
```

In the replacement string `$&` means the match itself, that is, the part of the source text that corresponds to `pattern:<body.*?>`. It gets replaced by itself plus `<h1>Hello</h1>`.
в заміненому рядку `$&` означає співпадіння саме по собі, тобто, частина вихідного тексту яка відповідає шаблону `pattern:<body.*?>`. Її замінено на неї ж плюс `<h1>Привіт</h1>`.

An alternative is to use lookbehind:
Альнернативою було би використання зворотньої перевірки:

```js run
let str = '...<body style="...">...';
str = str.replace(/(?<=<body.*?>)/, `<h1>Hello</h1>`);
str = str.replace(/(?<=<body.*?>)/, `<h1>Привіт</h1>`);

alert(str); // ...<body style="..."><h1>Hello</h1>...
alert(str); // ...<body style="..."><h1>Привіт</h1>...
```

As you can see, there's only lookbehind part in this regexp.
Як бачите, в цьому регулярному виразі є тільки зворотня перевірка.

It works like this:
- At every position in the text.
Це працює таким чином:
- На кожній позиції в тексті.
- Check if it's preceeded by `pattern:<body.*?>`.
- If it's so then we have the match.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# Insert After Head
# Вставка після Head

We have a string with an HTML Document.
У нас є рядок з HTML-документом.

Write a regular expression that inserts `<h1>Hello</h1>` immediately after `<body>` tag. The tag may have attributes.
Напишіть регулярний вираз який вставляє `<h1>Привіт</h1>` одразу після тегу `<body>`. Тег може мати атрибути.

For instance:
Приклад:

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

let str = `
<html>
Expand All @@ -17,13 +17,13 @@ let str = `
</html>
`;

str = str.replace(regexp, `<h1>Hello</h1>`);
str = str.replace(regexp, `<h1>Привіт</h1>`);
```

After that the value of `str` should be:
Після цього значення `str` має бути:
```html
<html>
<body style="height: 200px"><h1>Hello</h1>
<body style="height: 200px"><h1>Привіт</h1>
...
</body>
</html>
Expand Down
Loading