renovations

This commit is contained in:
Ilya Kantor 2015-03-06 17:10:55 +03:00
parent 2022aafc13
commit dceccedb58
60 changed files with 1730 additions and 272 deletions

View file

@ -1,12 +1,14 @@
# Наборы и диапазоны [...]
Если в регулярном выражении нескольки символов или символьных классов заключены в квадратные скобки `[…]`, то это означает "искать любой символ из указанных в `[…]`".
Если в регулярном выражении несколько символов или символьных классов заключены в квадратные скобки `[…]`, то это означает "искать любой символ из указанных в `[…]`".
[cut]
## Набор
Например, <code class="pattern">[еао]</code> означает любой символ из этих трёх: `'а'`, `'е'`, или `'о'`.
[cut]
Можно использовать квадратные скобки вместе с обычными символами.
Например:
Такое обозначение называют *набором*. Наборы используются в регулярном выражении наравне с обычными символами:
```js
//+ run
@ -14,7 +16,7 @@
alert( "Гоп-стоп".match( /[гт]оп/gi ) ); // "Гоп", "топ"
```
Несмотря на то, что в квадратных скобках несколько символов, в совпадении должен присутствовать *ровно один* из них.
Обратим внимание: несмотря на то, что в наборе указано несколько символов, в совпадении должен присутствовать *ровно один* из них.
Поэтому в примере ниже нет результатов:
@ -24,13 +26,22 @@ alert( "Гоп-стоп".match( /[гт]оп/gi ) ); // "Гоп", "топ"
alert( "Вуаля".match( /В[уа]ля/ ) ); // совпадений нет
```
Совпадение было бы, если бы после `"Ву"` шло сразу `"ля"`, например <code class="subject">Вуля</code> или если бы `"Ва"` сопровождалось `"ля"`, то есть <code class="subject">Валя</code>.
Поиск подразумевает:
<ul>
<li><code class="pattern">В</code>,</li>
<li>затем *одну* из букв набора <code class="pattern">[уа]</code>,</li>
<li>а затем <code class="pattern">ля</code></li>
</ul>
**Квадратные скобки могут также содержать *диапазоны символов*.**
Таким образом, совпадение было бы для строки <code class="match">Вуля</code> или <code class="match">Валя</code>.
## Диапазоны
Квадратные скобки могут также содержать *диапазоны символов*.
Например, <code class="pattern">[a-z]</code> -- произвольный символ от `a` до `z`, <code class="pattern">[0-5]</code> -- цифра от `0` до `5`.
В примере ниже мы будем искать `"x"`, после которого идёт два раза `[0-9A-F]` -- цифра или буква от A до F:
В примере ниже мы будем искать `"x"`, после которого идёт два раза любая цифра или буква от A до F:
```js
//+ run
@ -38,7 +49,7 @@ alert( "Вуаля".match( /В[уа]ля/ ) ); // совпадений нет
alert( "Exception 0xAF".match(/x[0-9A-F][0-9A-F]/g) );
```
Обратим внимание, в слове <code class="subject">Exception</code> есть сочетание <code class="subject">xce</code>, но оно не подошло, потому что буквы в нём маленькие, а в диапазоне -- большие.
Обратим внимание, в слове <code class="subject">Exception</code> есть сочетание <code class="subject">xce</code>, но оно не подошло, потому что буквы в нём маленькие, а в диапазоне <code class="pattern">[0-9A-F]</code> -- большие.
Если хочется искать и его тоже, можно добавить в скобки диапазон `a-f`: <code class="pattern">[0-9A-Fa-f]</code>. Или же просто указать у всего регулярного выражения флаг `i`.
@ -50,9 +61,9 @@ alert( "Exception 0xAF".match(/x[0-9A-F][0-9A-F]/g) );
<li>**\s** -- то же самое, что <code class="pattern">[\t\n\v\f\r ]</code> плюс несколько юникодных пробельных символов.</li>
</ul>
**В квадратных скобках можно использовать и диапазоны и символьные классы -- вместе.**
В квадратных скобках можно использовать и диапазоны и символьные классы -- вместе.
Например, нам нужно найти слова в тексте. Если оно на английском -- это достаточно просто:
Например, нам нужно найти все слова в тексте. Если они на английском -- это достаточно просто:
```js
//+ run
@ -72,7 +83,9 @@ alert( str.match( /\w+/g ) ); // null*!*
Ничего не найдено! Это можно понять, ведь <code class="pattern">\w</code> -- это именно английская букво-цифра, как можно видеть из аналога <code class="pattern">[a-zA-Z0-9_]</code>.
Чтобы находило слово на русском -- нужно использовать диапазон, например <code class="pattern">/[а-я]/</code>. А чтобы на обоих языках -- и то и другое вместе:
Чтобы находило слово на русском -- нужно использовать диапазон, например <code class="pattern">/[а-я]/</code>.
А чтобы на обоих языках -- и то и другое вместе:
```js
//+ run
@ -81,7 +94,9 @@ var str = "Солнце (the sun) встаёт!";
alert( str.match( /[\wа-я]+/gi ) ); // Солнце, the, sun, вста, т*!*
```
...Присмотритесь внимательно к предыдущему примеру! Вы видите странность? Оно не находит букву <code class="match">ё</code>, более того -- считает её разрывом в слове. Причина -- в кодировке юникод, она подробно раскрыта в главе [](/string). Буква `ё` лежит в стороне от основной кириллицы и её следует добавить в диапазон дополнительно, вот так:
...Присмотритесь внимательно к предыдущему примеру! Вы видите странность? Оно не находит букву <code class="match">ё</code>, более того -- считает её разрывом в слове. Причина -- в кодировке юникод, она подробно раскрыта в главе [](/string).
Буква `ё` лежит в стороне от основной кириллицы и её следует добавить в диапазон дополнительно, вот так:
```js
//+ run
@ -92,6 +107,8 @@ alert( str.match( /[\wа-яё]+/gi ) ); // Солнце, the, sun, встаёт*
Теперь всё в порядке.
## Диапазоны "кроме"
**Кроме обычных, существуют также *исключающие* диапазоны: <code class="pattern">[^…]</code>.**
Квадратные скобки, начинающиеся со знака каретки: <code class="pattern">[^…]</code> находят любой символ, *кроме указанных*.
@ -99,9 +116,9 @@ alert( str.match( /[\wа-яё]+/gi ) ); // Солнце, the, sun, встаёт*
Например:
<ul>
<li><code class="pattern">[^аеуо]</code> -- любой символ, кроме `'a'`, `'e'`, `'y'`, `'o'`</li>
<li><code class="pattern">[^0-9]</code> -- любая не-цифра, то же что `\D`</li>
<li><code class="pattern">[^\s]</code> -- любой не-пробельный символ, как и `\S`</li>
<li><code class="pattern">[^аеуо]</code> -- любой символ, кроме `'a'`, `'e'`, `'y'`, `'o'`.</li>
<li><code class="pattern">[^0-9]</code> -- любой символ, кроме цифры, то же что `\D`.</li>
<li><code class="pattern">[^\s]</code> -- любой не-пробельный символ, то же что `\S`.</li>
</ul>
Пример ниже ищет любые символы, кроме букв, цифр и пробелов:
@ -111,28 +128,31 @@ alert( str.match( /[\wа-яё]+/gi ) ); // Солнце, the, sun, встаёт*
alert( "alice15@gmail.com".match( /[^\d\sA-Z]/gi ) ); // "@", "."
```
**В квадратных скобках большинство специальных символов можно использовать без экранирования.**
## Не нужно экранирование
Обычно, если мы хотим искать именно точку, а не любой символ, или именно `"\d"`, а не произвольную цифру, то мы используем экранирование: указываем `\.` или `\\d`.
Обычно, если мы хотим искать именно точку, а не любой символ, или именно символ `\`, то мы используем экранирование: указываем `\.` или `\\`.
Но квадратные скобки подразумевают поиск одного символа из нескольких или из диапазона. Использование некоторых специальных символов внутри них не имело бы смысла, и они воспринимаются как обычные символы.
В квадратных скобках большинство специальных символов можно использовать без экранирования, если конечно ни не имеют какой-то особый смысл именно внутри квадратных скобок.
Это касается символов:
То есть, "как есть", без экранирования можно использовать символы:
<ul>
<li>точка <code class="pattern">'.'</code></li>
<li>плюс <code class="pattern">'+'</code></li>
<li>круглые скобки <code class="pattern">'( )'</code></li>
<li>дефис <code class="pattern">'-'</code>, если он находится в начале или конце квадратных скобок, то есть не выделяет диапазон.</li>
<li>символ каретки <code class="pattern">'^'</code>, если не находится в начале квадратных скобок, то есть кроме <code class="pattern">[\^..]</code>.</li>
<li>а также открывающая квадратная скобка <code class="pattern">'['</code></li>
<li>Точка <code class="pattern">'.'</code>.</li>
<li>Плюс <code class="pattern">'+'</code>.</li>
<li>Круглые скобки <code class="pattern">'( )'</code>.</li>
<li>Дефис <code class="pattern">'-'</code>, если он находится в начале или конце квадратных скобок, то есть не выделяет диапазон.</li>
<li>Символ каретки <code class="pattern">'^'</code>, если не находится в начале квадратных скобок.</li>
<li>А также открывающая квадратная скобка <code class="pattern">'['</code>.</li>
</ul>
То есть, точка `"."` в квадратных скобках означает не "любой символ", а обычную точку.
Например, регэксп <code class="pattern">[-().^+]</code> ищет один из символов `-().^`. В данном контексте эти символы не являются специальными.
Регэксп <code class="pattern">[.,]</code> ищет один из символов "точка" или "запятая".
В примере ниже регэксп <code class="pattern">[-().^+]</code> ищет один из символов `-().^`. Они не экранированы:
```js
//+ run
// Без экранирования
var re = /[-().^+]/g;
alert( "1 + 2 - 3".match(re) ); // найдёт +, -
@ -142,6 +162,7 @@ alert( "1 + 2 - 3".match(re) ); // найдёт +, -
```js
//+ run
// Всё заэкранировали
var re = /[\-\(\)\.\^\+]/g;
alert( "1 + 2 - 3".match(re) ); // тоже работает: +, -