This commit is contained in:
Ilya Kantor 2019-09-04 19:35:17 +03:00
parent f21cb0a2f4
commit fc0b18538d
4 changed files with 30 additions and 31 deletions

View file

@ -1,6 +1,6 @@
Ответ: `pattern:\b\d\d:\d\d\b`.
The answer: `pattern:\b\d\d:\d\d\b`.
```js run
alert( "Завтрак в 09:00 в комнате 123:456.".match( /\b\d\d:\d\d\b/ ) ); // 09:00
alert( "Breakfast at 09:00 in the room 123:456.".match( /\b\d\d:\d\d\b/ ) ); // 09:00
```

View file

@ -1,9 +1,9 @@
# Найдите время
# Find the time
Время имеет формат: `часы:минуты`. И часы, и минуты имеют две цифры, например, `09:00`.
The time has a format: `hours:minutes`. Both hours and minutes has two digits, like `09:00`.
Введите регулярное выражение, чтобы найти время в строке: `subject:Завтрак в 09:00 в комнате 123:456.`
Make a regexp to find time in the string: `subject:Breakfast at 09:00 in the room 123:456.`
P.S. В этой задаче пока нет необходимости проверять правильность времени, поэтому `25:99` также может быть верным результатом.
P.S. In this task there's no need to check time correctness yet, so `25:99` can also be a valid result.
P.P.S. Регулярное выражение не должно находить `123:456`.
P.P.S. The regexp shouldn't match `123:456`.

View file

@ -25,29 +25,28 @@ So, it matches the pattern `pattern:\bHello\b`, because:
1. At the beginning of the string matches the first test `pattern:\b`.
2. Then matches the word `pattern:Hello`.
3. Then the test `pattern:\b` - matches again, as we're between `subject:o` and a space.
3. Then the test `pattern:\b` matches again, as we're between `subject:o` and a space.
Шаблон `pattern:\bJava\b` также совпадёт. Но не `pattern:\bHell\b` (потому что после `subject:l` нет границы слова), и не `pattern:Java!\b` (восклицательный знак не является "символом слова" `pattern:\w`, поэтому после него нет границы слова).
The pattern `pattern:\bJava\b` would also match. But not `pattern:\bHell\b` (because there's no word boundary after `l`) and not `Java!\b` (because the exclamation sign is not a wordly character `pattern:\w`, so there's no word boundary after it).
```js run
alert( "Hello, Java!".match(/\bHello\b/) ); // Hello
alert( "Hello, Java!".match(/\bJava\b/) ); // Java
alert( "Hello, Java!".match(/\bHell\b/) ); // null (нет совпадения)
alert( "Hello, Java!".match(/\bJava!\b/) ); // null (нет совпадения)
alert( "Hello, Java!".match(/\bHell\b/) ); // null (no match)
alert( "Hello, Java!".match(/\bJava!\b/) ); // null (no match)
```
Так как `pattern:\b` является проверкой, то не добавляет символ после границы к результату.
We can use `pattern:\b` not only with words, but with digits as well.
Мы можем использовать `pattern:\b` не только со словами, но и с цифрами.
Например, регулярное выражение `pattern:\b\d\d\b` ищет отдельно стоящие двузначные числа. Другими словами, оно требует, чтобы до и после `pattern:\d\d` был символ, отличный от `pattern:\w` (или начало/конец строки)
For example, the pattern `pattern:\b\d\d\b` looks for standalone 2-digit numbers. In other words, it looks for 2-digit numbers that are surrounded by characters different from `pattern:\w`, such as spaces or punctuation (or text start/end).
```js run
alert( "1 23 456 78".match(/\b\d\d\b/g) ); // 23,78
alert( "12,34,56".match(/\b\d\d\b/g) ); // 12,34,56
```
```warn header="Граница слова `pattern:\b` не работает для алфавитов, не основанных на латинице"
Проверка границы слова `pattern:\b` проверяет границу, должно быть `pattern:\w` с одной стороны и "не `pattern:\w`" - с другой.
```warn header="Word boundary `pattern:\b` doesn't work for non-latin alphabets"
The word boundary test `pattern:\b` checks that there should be `pattern:\w` on the one side from the position and "not `pattern:\w`" - on the other side.
Но `pattern:\w` означает латинскую букву (или цифру или знак подчёркивания), поэтому проверка не будет работать для других символов (например, кириллицы или иероглифов).
But `pattern:\w` means a latin letter `a-z` (or a digit or an underscore), so the test doesn't work for other characters, e.g. cyrillic letters or hieroglyphs.
```

View file

@ -1,7 +1,7 @@
# Escaping, special characters
As we've seen, a backslash `"\"` is used to denote character classes. So it's a special character in regexps (just like in a regular string).
As we've seen, a backslash `pattern:\` is used to denote character classes, e.g. `pattern:\d`. So it's a special character in regexps (just like in regular strings).
There are other special characters as well, that have special meaning in a regexp. They are used to do more powerful searches. Here's a full list of them: `pattern:[ \ ^ $ . | ? * + ( )`.
@ -9,7 +9,7 @@ Don't try to remember the list -- soon we'll deal with each of them separately a
## Escaping
Let's say we want to find a dot literally. Not "any character", but just a dot.
Let's say we want to find literally a dot. Not "any character", but just a dot.
To use a special character as a regular one, prepend it with a backslash: `pattern:\.`.
@ -43,10 +43,10 @@ Here's what a search for a slash `'/'` looks like:
alert( "/".match(/\//) ); // '/'
```
On the other hand, if we're not using `/.../`, but create a regexp using `new RegExp`, then we don't need to escape it:
On the other hand, if we're not using `pattern:/.../`, but create a regexp using `new RegExp`, then we don't need to escape it:
```js run
alert( "/".match(new RegExp("/")) ); // '/'
alert( "/".match(new RegExp("/")) ); // finds /
```
## new RegExp
@ -61,25 +61,25 @@ let reg = new RegExp("\d\.\d");
alert( "Chapter 5.1".match(reg) ); // null
```
The search worked with `pattern:/\d\.\d/`, but with `new RegExp("\d\.\d")` it doesn't work, why?
The similar search in one of previous examples worked with `pattern:/\d\.\d/`, but `new RegExp("\d\.\d")` doesn't work, why?
The reason is that backslashes are "consumed" by a string. Remember, regular strings have their own special characters like `\n`, and a backslash is used for escaping.
The reason is that backslashes are "consumed" by a string. As we may recall, regular strings have their own special characters, such as `\n`, and a backslash is used for escaping.
Please, take a look, what "\d\.\d" really is:
Here's how "\d\.\d" is preceived:
```js run
alert("\d\.\d"); // d.d
```
The quotes "consume" backslashes and interpret them, for instance:
String quotes "consume" backslashes and interpret them on their own, for instance:
- `\n` -- becomes a newline character,
- `\u1234` -- becomes the Unicode character with such code,
- ...And when there's no special meaning: like `pattern:\d` or `\z`, then the backslash is simply removed.
So the call to `new RegExp` gets a string without backslashes. That's why the search doesn't work!
So `new RegExp` gets a string without backslashes. That's why the search doesn't work!
To fix it, we need to double backslashes, because quotes turn `\\` into `\`:
To fix it, we need to double backslashes, because string quotes turn `\\` into `\`:
```js run
*!*
@ -94,6 +94,6 @@ alert( "Chapter 5.1".match(reg) ); // 5.1
## Summary
- To search special characters `pattern:[ \ ^ $ . | ? * + ( )` literally, we need to prepend them with `\` ("escape them").
- To search for special characters `pattern:[ \ ^ $ . | ? * + ( )` literally, we need to prepend them with a backslash `\` ("escape them").
- We also need to escape `/` if we're inside `pattern:/.../` (but not inside `new RegExp`).
- When passing a string `new RegExp`, we need to double backslashes `\\`, cause strings consume one of them.
- When passing a string `new RegExp`, we need to double backslashes `\\`, cause string quotes consume one of them.