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