Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Alternation (OR) |#388

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
dolgachio merged 3 commits intojavascript-tutorial:masterfromvladiuskor:master
Oct 24, 2022
Merged
Show file tree
Hide file tree
Changes fromall 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
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@

The first idea can be to list the languages with`|` in-between.
Перше, що може спасти на думку -- перерахувати мови, розділивши їх за допомогою`|`.

But that doesn't work right:
Однак, це не спрацює належним чином:

```js run
let regexp = /Java|JavaScript|PHP|C|C\+\+/g;
Expand All@@ -11,18 +11,18 @@ let str = "Java, JavaScript, PHP, C, C++";
alert( str.match(regexp) ); // Java,Java,PHP,C,C
```

The regular expression engine looks for alternations one-by-one. That is: first it checks if we have`match:Java`,otherwise--looks for`match:JavaScript`and so on.
Механізм регулярних виразів шукає альтернації одну за одною. Тобто, спочатку він перевіряє, чи маємо ми`match:Java`,якщо немає--шукає`match:JavaScript`і так далі.

As a result, `match:JavaScript`can never be found, just because`match:Java`is checked first.
У результаті, `match:JavaScript`ніколи не буде знайден, лише тому що`match:Java`перевіряється першою.

The same with`match:C`and `match:C++`.
Так само і з мовами`match:C`та `match:C++`.

There are two solutions for that problem:
Існує два розв'язання цієї проблеми:

1.Change the order to check the longer match first: `pattern:JavaScript|Java|C\+\+|C|PHP`.
2.Merge variants with the same start: `pattern:Java(Script)?|C(\+\+)?|PHP`.
1.Змінити порядок, щоб спочатку перевірялись довші співпадіння: `pattern:JavaScript|Java|C\+\+|C|PHP`.
2.З’єднати варіанти, які починаються однаково: `pattern:Java(Script)?|C(\+\+)?|PHP`.

In action:
У дії:

```js run
let regexp = /Java(Script)?|C(\+\+)?|PHP/g;
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
#Find programming languages
#Знайдіть мову програмування

There are many programming languages, for instance Java, JavaScript, PHP, C, C++.
Існує багато мов програмування, наприклад Java, JavaScript, PHP, C, C++.

Create a regexp that finds them in the string `subject:Java JavaScript PHP C++ C`:
Напишіть регулярний вираз, який знаходить вищезгадані мови у рядку `subject:Java JavaScript PHP C++ C`:

```js
let regexp = /your regexp/g;
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@

Opening tag is `pattern:\[(b|url|quote)]`.
Відкриваючий тег -- це `pattern:\[(b|url|quote)]`.

Then to find everything till the closing tag--let's use the pattern`pattern:.*?`with flag `pattern:s`to match any character including the newline and then add a backreference to the closing tag.
Потім, щоб знайти все, до закриваючого тегу--використаємо вираз`pattern:.*?`з прапорцем `pattern:s` щоб знайти будь-які символи, включно з новим рядком, а потім додати зворотне посилання до закриваючого тегу.

The full pattern: `pattern:\[(b|url|quote)\].*?\[/\1]`.
Цілий вираз: `pattern:\[(b|url|quote)\].*?\[/\1]`.

In action:
У дії:

```js run
let regexp = /\[(b|url|quote)].*?\[\/\1]/gs;
Expand All@@ -20,4 +20,4 @@ let str = `
alert( str.match(regexp) ); // [b]hello![/b],[quote][url]http://google.com[/url][/quote]
```

Please note that besides escaping `pattern:[`,we had to escape a slash for the closing tag`pattern:[\/\1]`,because normally the slash closes the pattern.
Зверніть увагу, що крім екранування `pattern:[`,нам необхідно екранувати слеш у закриваючому тегу`pattern:[\/\1]`,бо зазвичай слеш завершує вираз.
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,47 @@
#Find bbtag pairs
#Знайдіть пари ВВ-тегів

A "bb-tag" looks like `[tag]...[/tag]`,where `tag`is one of: `b`, `url`or `quote`.
ВВ-тег має вигляд `[tag]...[/tag]`,де `tag`-- це один з: `b`, `url`або `quote`.

For instance:
Наприклад:
```
[b]text[/b]
[b]текст[/b]
[url]http://google.com[/url]
```

BB-tags can be nested. But a tag can't be nested into itself, for instance:
ВВ-теги можуть бути вкладеними. Але тег не може бути вкладеним сам у себе, наприклад:

```
Normal:
Може бути:
[url] [b]http://google.com[/b] [/url]
[quote] [b]text[/b] [/quote]
[quote] [b]текст[/b] [/quote]

Can't happen:
Не може бути:
[b][b]text[/b][/b]
```

Tags can contain line breaks, that's normal:
Теги можуть мати розрив рядків, це допустимо:

```
[quote]
[b]text[/b]
[b]текст[/b]
[/quote]
```

Create a regexp to find all BB-tags with their contents.
Створіть регулярний вираз для пошуку всіх BB-тегів та їх вмісту.

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

```js
let regexp = /your regexp/flags;
let regexp = /ваш регулярний вираз/прапорці;

let str = "..[url]http://google.com[/url]..";
alert( str.match(regexp) ); // [url]http://google.com[/url]
```

If tags are nested, then we need the outer tag (if we want we can continue the search in its content):
Якщо теги вкладені, тоді необхідно шукати зовнішній тег (за бажанням, можна продовжити пошук всередині його вмісту):

```js
let regexp = /your regexp/flags;
let regexp = /ваш регулярний вираз/прапорці;

let str = "..[url][b]http://google.com[/b][/url]..";
alert( str.match(regexp) ); // [url][b]http://google.com[/b][/url]
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
The solution: `pattern:/"(\\.|[^"\\])*"/g`.
Рішення: `pattern:/"(\\.|[^"\\])*"/g`.

Step by step:
Крок за кроком:

-First we look for an opening quote `pattern:"`
-Then if we have a backslash`pattern:\\` (we have to double it in the pattern because it is a special character),then any character is fine after it (a dot).
-Otherwise we take any character except a quote (that would mean the end of the string) and a backslash (to prevent lonely backslashes, the backslash is only used with some other symbol after it): `pattern:[^"\\]`
- ...And so on till the closing quote.
-Спочатку шукаємо відкриваючі лапки `pattern:"`
-Потім, якщо є зворотній слеш`pattern:\\` (ми повинні подвоїти його у виразі, тому що це спеціальний символ),то після нього також підійде будь-який символ (крапка).
-В іншому випадку, беремо будь-який символ, крім лапок (це означало б кінець рядка) та зворотнього слешу (щоб запобігти поодиноким зворотнім слешам, бо вони використовуються тільки з іншими символами після них): `pattern:[^"\\]`
- ...І так далі, до закриваючих лапок.

In action:
У дії:

```js run
let regexp = /"(\\.|[^"\\])*"/g;
let str = ' .. "test me" .. "Say \\"Hello\\"!" .. "\\\\ \\"" .. ';
let str = ' .. "протестуй мене" .. "Скажи \\"Привіт\\"!" .. "\\\\ \\"" .. ';

alert( str.match(regexp) ); // "test me","Say \"Hello\"!","\\ \""
alert( str.match(regexp) ); // "протестуй мене","Скажи \"Привіт\"!","\\ \""
```
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,32 @@
#Find quoted strings
#Знайдіть рядки у лапках

Create a regexp to find strings in double quotes `subject:"..."`.
Створіть регулярний вираз для пошуку рядків у подвійних лапках `subject:"..."`.

The strings should support escaping, the same way as JavaScript strings do. For instance, quotes can be inserted as `subject:\"` a newline as `subject:\n`,and the slash itself as `subject:\\`.
Рядки повинні підтримувати екранування за допомогою зворотнього слеша, аналогічно з рядками в JavaScript. Наприклад, лапки можуть бути вставлені як `subject:\"`, новий рядок як `subject:\n`,та сам зворотній слеш як `subject:\\`.

```js
let str = "Just like \"here\".";
let str = "Як ось \"тут\".";
```

Please note, in particular, that an escaped quote`subject:\"`does not end a string.
Зокрема, зверніть увагу, що екрановані лапки`subject:\"`не завершують рядок.

So we should search from one quote to the other ignoring escaped quotes on the way.
Тому нам необхідно шукати від одних лапок до інших, ігноруючи екрановані лапки на нашому шляху.

That's the essential part of the task, otherwise it would be trivial.
У цьому і полягає основна складність завдання, адже без цієї умови -- рішення було б елементарним.

Examples of strings to match:
Приклади відповідних рядків:
```js
.. *!*"test me"*/!* ..
.. *!*"Say \"Hello\"!"*/!* ... (escaped quotes inside)
.. *!*"\\"*/!* .. (double slash inside)
.. *!*"\\ \""*/!* .. (double slash and an escaped quote inside)
.. *!*"протестуй мене"*/!* ..
.. *!*"Скажи \"Привіт\"!"*/!* ... (екрановані рядки всередині)
.. *!*"\\"*/!* .. (подвійний слеш всередині)
.. *!*"\\ \""*/!* .. (подвійний слеш та екрановані лапки всередині)
```

In JavaScriptwe need to double the slashes to pass them right into the string, like this:
У JavaScriptнам потрібно подвоювати слеші, щоб передати їх в рядок, як тут:

```js run
let str = ' .. "test me" .. "Say \\"Hello\\"!" .. "\\\\ \\"" .. ';
let str = ' .. "протестуй мене" .. "Скажи \\"Привіт\\"!" .. "\\\\ \\"" .. ';

//the in-memory string
alert(str); // .. "test me" .. "Say \"Hello\"!" .. "\\ \"" ..
//Рядок у пам’яті
alert(str); // .. "протестуй мене" .. "Скажи \"Привіт\"!" .. "\\ \"" ..
```
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@

The pattern start is obvious: `pattern:<style`.
Початок шаблону є очевидним: `pattern:<style`.

...But then we can't simply write`pattern:<style.*?>`,because`match:<styler>`would match it.
...Однак далі, ми не можемо просто прописати`pattern:<style.*?>`,тому що`match:<styler>`відповідає цьому виразу.

We need either a space after`match:<style`and then optionally something else or the ending `match:>`.
Потім, після`match:<style`має бути або пробіл, за яким може бути ще щось, або закриття тегу `match:>`.

In the regexp language: `pattern:<style(>|\s.*?>)`.
Мовою регулярних виразів: `pattern:<style(>|\s.*?>)`.

In action:
У дії:

```js run
let regexp = /<style(>|\s.*?>)/g;
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
#Find the full tag
#Знайдіть цілий тег

Write a regexp to find the tag`<style...>`.It should match the full tag: it may have no attributes`<style>` or have several of them `<style type="..." id="...">`.
Напишіть регулярний вираз, який шукає тег`<style...>`.Шаблон має шукати цілий тег: він може як і не мати атрибутів`<style>`, так і мати їх декілька `<style type="..." id="...">`.

...But the regexp should not match `<styler>`!
...Проте регулярний вираз не повинен знаходити `<styler>`!

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

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

alert( '<style> <styler> <style test="...">'.match(regexp) ); // <style>, <style test="...">
```
60 changes: 30 additions & 30 deletions9-regular-expressions/13-regexp-alternation/article.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,67 @@
#Alternation (OR) |
#Альтернація (АБО) |

Alternation is the term in regular expression that is actually a simple "OR".
Альтернація -- це термін у регулярному виразі, який насправді є простим "АБО".

In a regular expression it is denoted with a vertical line character `pattern:|`.
Вона позначається символом вертикальної лінії `pattern:|`.

For instance, we need to find programming languages: HTML, PHP, Javaor JavaScript.
Наприклад, нам треба знайти мови програмування: HTML, PHP, Javaабо JavaScript.

The corresponding regexp: `pattern:html|php|java(script)?`.
Відповідний регулярний вираз: `pattern:html|php|java(script)?`.

A usage example:
Приклад використання:

```js run
let regexp = /html|php|css|java(script)?/gi;

let str = "First HTML appeared, then CSS,then JavaScript";
let str = "Першим з’явився HTML, потім CSS,далі JavaScript";

alert( str.match(regexp) ); // 'HTML', 'CSS', 'JavaScript'
```

We already saw a similar thing--square brackets. They allow to choose between multiple characters, for instance`pattern:gr[ae]y`matches `match:gray`or `match:grey`.
Ми вже бачили подібне--квадратні дужки. Вони дозволяють обирати між декількома символами, наприклад`pattern:gr[ae]y`знайде `match:gray`або `match:grey`.

Square brackets allow only characters or character classes. Alternation allows any expressions. A regexp `pattern:A|B|C`means one of expressions`A`, `B`or `C`.
Квадратні дужки дозволяють працювати тільки з символами, або наборами символів. Натомість Альтернація працює з будь-якими виразами. Регулярний вираз `pattern:A|B|C`означає пошук одного з символів:`A`, `B`або `C`.

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

- `pattern:gr(a|e)y`means exactly the same as `pattern:gr[ae]y`.
- `pattern:gra|ey`means `match:gra`or `match:ey`.
- `pattern:gr(a|e)y`означає те саме, що й `pattern:gr[ae]y`.
- `pattern:gra|ey`означає `match:gra`або `match:ey`.

To apply alternation to a chosen part of the pattern, we can enclose it in parentheses:
- `pattern:I love HTML|CSS`matches `match:I love HTML`or `match:CSS`.
- `pattern:I love (HTML|CSS)`matches `match:I love HTML`or `match:I love CSS`.
Для того, щоб використати альтернацію з обраною частиною шаблону, ми можемо загорнути його у дужки:
- `pattern:Я люблю HTML|CSS`знайде `match:Я люблю HTML`або `match:CSS`.
- `pattern:Я люблю (HTML|CSS)`знайде `match:Я люблю HTML`або `match:Я люблю CSS`.

##Example: regexp for time
##Приклад: регулярний вираз для часу

In previous articles there was a task to build a regexp for searching time in the form `hh:mm`,for instance`12:00`.But a simple `pattern:\d\d:\d\d`is too vague. It accepts `25:99`as the time (as99minutes match the pattern, but that time is invalid).
У попередніх статтях було завдання написати регулярний вираз для пошуку часу у форматі `гг:хх`,наприклад`12:00`.Однак простий шаблон `pattern:\d\d:\d\d`недостатньо точний. Він приймає `25:99`як час (99хвилин підходять до шаблону, однак цей час не є вірним).

How can we make a better pattern?
Як ми можемо написати кращий шаблон?

We can use more careful matching. First, the hours:
Можна зробити більш ретельне порівняння. Спочатку, години:

-If the first digit is`0`or `1`,then the next digit can be any: `pattern:[01]\d`.
-Otherwise, if the first digit is `2`,then the next must be `pattern:[0-3]`.
- (no other first digit is allowed)
-Якщо перша цифра`0`або `1`,тоді наступна може бути будь-якою цифрою: `pattern:[01]\d`.
-В іншому випадку, якщо перша цифра `2`,тоді наступна має бути від 0 до 3 `pattern:[0-3]`.
- (іншої першої цифри бути не може)

We can write both variants in a regexp using alternation: `pattern:[01]\d|2[0-3]`.
Ми можемо написати обидва варіанти у регулярному виразі за допомогою альтернації: `pattern:[01]\d|2[0-3]`.

Next, minutes must be from `00`to `59`.In the regular expression language that can be written as`pattern:[0-5]\d`:the first digit`0-5`,and then any digit.
Далі, хвилини мають бути від `00`до `59`.Мовою регулярних виразів це може бути написано таким чином`pattern:[0-5]\d`:перша цифра`0-5`,а за нею будь-яка.

If we glue hours and minutes together, we get the pattern: `pattern:[01]\d|2[0-3]:[0-5]\d`.
Якщо ми зберемо шаблони годин та хвилин докупи, то вийде ось так: `pattern:[01]\d|2[0-3]:[0-5]\d`.

We're almost done, but there's a problem. The alternation`pattern:|`now happens to be between`pattern:[01]\d`and `pattern:2[0-3]:[0-5]\d`.
Майже готово, однак тут є проблема. Альтернація`pattern:|`зараз відбувається між`pattern:[01]\d`та `pattern:2[0-3]:[0-5]\d`.

That is: minutes are added to the second alternation variant, here's a clear picture:
Тобто: хвилини додалися до другого варіанту альтернації, більш наочна картинка:

```
[01]\d | 2[0-3]:[0-5]\d
```

That pattern looks for `pattern:[01]\d`or `pattern:2[0-3]:[0-5]\d`.
Такий шаблон буде шукати `pattern:[01]\d`або `pattern:2[0-3]:[0-5]\d`.

But that's wrong, the alternation should only be used in the "hours" part of the regular expression, to allow `pattern:[01]\d`OR `pattern:2[0-3]`.Let's correct that by enclosing "hours" into parentheses: `pattern:([01]\d|2[0-3]):[0-5]\d`.
Але це невірно. Нам необхідно, щоб альтернація використовувалась тільки у частині регулярного виразу, який відноситься до "годин", щоб дозволити `pattern:[01]\d`АБО `pattern:2[0-3]`.Виправимо це, огорнувши "години" у дужки: `pattern:([01]\d|2[0-3]):[0-5]\d`.

The final solution:
Остаточне рішення:

```js run
let regexp = /([01]\d|2[0-3]):[0-5]\d/g;
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp