# Наборы и диапазоны [...] Если в регулярном выражении несколько символов или символьных классов заключены в квадратные скобки `[…]`, то это означает "искать любой символ из указанных в `[…]`". [cut] ## Набор Например, [еао] означает любой символ из этих трёх: `'а'`, `'е'`, или `'о'`. Такое обозначение называют *набором*. Наборы используются в регулярном выражении наравне с обычными символами: ```js //+ run // найти [г или т], а затем "оп" alert( "Гоп-стоп".match(/[гт]оп/gi) ); // "Гоп", "топ" ``` Обратим внимание: несмотря на то, что в наборе указано несколько символов, в совпадении должен присутствовать *ровно один* из них. Поэтому в примере ниже нет результатов: ```js //+ run // найти "В", затем [у или а], затем "ля" alert( "Вуаля".match(/В[уа]ля/) ); // совпадений нет ``` Поиск подразумевает: Таким образом, совпадение было бы для строки Вуля или Валя. ## Диапазоны Квадратные скобки могут также содержать *диапазоны символов*. Например, [a-z] -- произвольный символ от `a` до `z`, [0-5] -- цифра от `0` до `5`. В примере ниже мы будем искать `"x"`, после которого идёт два раза любая цифра или буква от A до F: ```js //+ run // найдёт "xAF" alert( "Exception 0xAF".match(/x[0-9A-F][0-9A-F]/g) ); ``` Обратим внимание, в слове Exception есть сочетание xce, но оно не подошло, потому что буквы в нём маленькие, а в диапазоне [0-9A-F] -- большие. Если хочется искать и его тоже, можно добавить в скобки диапазон `a-f`: [0-9A-Fa-f]. Или же просто указать у всего регулярного выражения флаг `i`. **Символьные классы -- всего лишь более короткие записи для диапазонов, в частности:** В квадратных скобках можно использовать и диапазоны и символьные классы -- вместе. Например, нам нужно найти все слова в тексте. Если они на английском -- это достаточно просто: ```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*!* ``` Ничего не найдено! Это можно понять, ведь \w -- это именно английская букво-цифра, как можно видеть из аналога [a-zA-Z0-9_]. Чтобы находило слово на русском -- нужно использовать диапазон, например /[а-я]/. А чтобы на обоих языках -- и то и другое вместе: ```js //+ run var str = "Солнце (the sun) встаёт!"; alert( str.match(/[\wа-я]+/gi) ); // Солнце, the, sun, вста, т*!* ``` ...Присмотритесь внимательно к предыдущему примеру! Вы видите странность? Оно не находит букву ё, более того -- считает её разрывом в слове. Причина -- в кодировке юникод, она подробно раскрыта в главе [](/string). Буква `ё` лежит в стороне от основной кириллицы и её следует добавить в диапазон дополнительно, вот так: ```js //+ run var str = "Солнце (the sun) встаёт!"; alert( str.match(/[\wа-яё]+/gi) ); // Солнце, the, sun, встаёт*!* ``` Теперь всё в порядке. ## Диапазоны "кроме" **Кроме обычных, существуют также *исключающие* диапазоны: [^…].** Квадратные скобки, начинающиеся со знака каретки: [^…] находят любой символ, *кроме указанных*. Например: Пример ниже ищет любые символы, кроме букв, цифр и пробелов: ```js //+ run alert( "alice15@gmail.com".match(/[^\d\sA-Z]/gi) ); // "@", "." ``` ## Не нужно экранирование Обычно, если мы хотим искать именно точку, а не любой символ, или именно символ `\`, то мы используем экранирование: указываем `\.` или `\\`. В квадратных скобках большинство специальных символов можно использовать без экранирования, если конечно ни не имеют какой-то особый смысл именно внутри квадратных скобок. То есть, "как есть", без экранирования можно использовать символы: То есть, точка `"."` в квадратных скобках означает не "любой символ", а обычную точку. Регэксп [.,] ищет один из символов "точка" или "запятая". В примере ниже регэксп [-().^+] ищет один из символов `-().^`. Они не экранированы: ```js //+ run // Без экранирования var re = /[-().^+]/g; alert( "1 + 2 - 3".match(re) ); // найдёт +, - ``` ...Впрочем, даже если вы решите "на всякий случай" заэкранировать эти символы, поставив перед ними обратный слэш `\` -- вреда не будет: ```js //+ run // Всё заэкранировали var re = /[\-\(\)\.\^\+]/g; alert( "1 + 2 - 3".match(re) ); // тоже работает: +, - ```