149 lines
8.4 KiB
Markdown
149 lines
8.4 KiB
Markdown
# Наборы и диапазоны [...]
|
||
|
||
Если в регулярном выражении нескольки символов или символьных классов заключены в квадратные скобки `[…]`, то это означает "искать любой символ из указанных в `[…]`".
|
||
|
||
Например, <code class="pattern">[еао]</code> означает любой символ из этих трёх: `'а'`, `'е'`, или `'о'`.
|
||
[cut]
|
||
Можно использовать квадратные скобки вместе с обычными символами.
|
||
|
||
Например:
|
||
|
||
```js
|
||
//+ run
|
||
// найти [г или т], а затем "оп"
|
||
alert( "Гоп-стоп".match( /[гт]оп/gi ) ); // "Гоп", "топ"
|
||
```
|
||
|
||
Несмотря на то, что в квадратных скобках несколько символов, в совпадении должен присутствовать *ровно один* из них.
|
||
|
||
Поэтому в примере ниже нет результатов:
|
||
|
||
```js
|
||
//+ run
|
||
// найти "В", затем [у или а], затем "ля"
|
||
alert( "Вуаля".match( /В[уа]ля/ ) ); // совпадений нет
|
||
```
|
||
|
||
Совпадение было бы, если бы после `"Ву"` шло сразу `"ля"`, например <code class="subject">Вуля</code> или если бы `"Ва"` сопровождалось `"ля"`, то есть <code class="subject">Валя</code>.
|
||
|
||
**Квадратные скобки могут также содержать *диапазоны символов*.**
|
||
|
||
Например, <code class="pattern">[a-z]</code> -- произвольный символ от `a` до `z`, <code class="pattern">[0-5]</code> -- цифра от `0` до `5`.
|
||
|
||
В примере ниже мы будем искать `"x"`, после которого идёт два раза `[0-9A-F]` -- цифра или буква от A до F:
|
||
|
||
```js
|
||
//+ run
|
||
// найдёт "xAF"
|
||
alert( "Exception 0xAF".match(/x[0-9A-F][0-9A-F]/g) );
|
||
```
|
||
|
||
Обратим внимание, в слове <code class="subject">Exception</code> есть сочетание <code class="subject">xce</code>, но оно не подошло, потому что буквы в нём маленькие, а в диапазоне -- большие.
|
||
|
||
Если хочется искать и его тоже, можно добавить в скобки диапазон `a-f`: <code class="pattern">[0-9A-Fa-f]</code>. Или же просто указать у всего регулярного выражения флаг `i`.
|
||
|
||
**Символьные классы -- всего лишь более короткие записи для диапазонов, в частности:**
|
||
|
||
<ul>
|
||
<li>**\d** -- то же самое, что <code class="pattern">[0-9]</code>,</li>
|
||
<li>**\w** -- то же самое, что <code class="pattern">[a-zA-Z0-9_]</code>,</li>
|
||
<li>**\s** -- то же самое, что <code class="pattern">[\t\n\v\f\r ]</code> плюс несколько юникодных пробельных символов.</li>
|
||
</ul>
|
||
|
||
**В квадратных скобках можно использовать и диапазоны и символьные классы -- вместе.**
|
||
|
||
Например, нам нужно найти слова в тексте. Если оно на английском -- это достаточно просто:
|
||
|
||
```js
|
||
//+ run
|
||
var str = "The sun is rising!";
|
||
|
||
alert( str.match( /\w+/g ) ); // The, sun, is, rising*!*
|
||
```
|
||
|
||
А если есть слова и на русском?
|
||
|
||
```js
|
||
//+ run
|
||
var str = "Солнце встаёт!";
|
||
|
||
alert( str.match( /\w+/g ) ); // null*!*
|
||
```
|
||
|
||
Ничего не найдено! Это можно понять, ведь <code class="pattern">\w</code> -- это именно английская букво-цифра, как можно видеть из аналога <code class="pattern">[a-zA-Z0-9_]</code>.
|
||
|
||
Чтобы находило слово на русском -- нужно использовать диапазон, например <code class="pattern">/[а-я]/</code>. А чтобы на обоих языках -- и то и другое вместе:
|
||
|
||
```js
|
||
//+ run
|
||
var str = "Солнце (the sun) встаёт!";
|
||
|
||
alert( str.match( /[\wа-я]+/gi ) ); // Солнце, the, sun, вста, т*!*
|
||
```
|
||
|
||
...Присмотритесь внимательно к предыдущему примеру! Вы видите странность? Оно не находит букву <code class="match">ё</code>, более того -- считает её разрывом в слове. Причина -- в кодировке юникод, она подробно раскрыта в главе [](/string). Буква `ё` лежит в стороне от основной кириллицы и её следует добавить в диапазон дополнительно, вот так:
|
||
|
||
```js
|
||
//+ run
|
||
var str = "Солнце (the sun) встаёт!";
|
||
|
||
alert( str.match( /[\wа-яё]+/gi ) ); // Солнце, the, sun, встаёт*!*
|
||
```
|
||
|
||
Теперь всё в порядке.
|
||
|
||
**Кроме обычных, существуют также *исключающие* диапазоны: <code class="pattern">[^…]</code>.**
|
||
|
||
Квадратные скобки, начинающиеся со знака каретки: <code class="pattern">[^…]</code> находят любой символ, *кроме указанных*.
|
||
|
||
Например:
|
||
|
||
<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>
|
||
</ul>
|
||
|
||
Пример ниже ищет любые символы, кроме букв, цифр и пробелов:
|
||
|
||
```js
|
||
//+ run
|
||
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>
|
||
</ul>
|
||
|
||
То есть, точка `"."` в квадратных скобках означает не "любой символ", а обычную точку.
|
||
|
||
Например, регэксп <code class="pattern">[-().^+]</code> ищет один из символов `-().^`. В данном контексте эти символы не являются специальными.
|
||
|
||
```js
|
||
//+ run
|
||
var re = /[-().^+]/g;
|
||
|
||
alert( "1 + 2 - 3".match(re) ); // найдёт +, -
|
||
```
|
||
|
||
...Впрочем, даже если вы решите "на всякий случай" заэкранировать эти символы, поставив перед ними обратный слэш `\` -- вреда не будет:
|
||
|
||
```js
|
||
//+ run
|
||
var re = /[\-\(\)\.\^\+]/g;
|
||
|
||
alert( "1 + 2 - 3".match(re) ); // тоже работает: +, -
|
||
```
|
||
|