en.javascript.info/10-regular-expressions-javascript/5-regexp-character-sets-and-ranges/article.md
2015-02-27 13:21:58 +03:00

8.4 KiB
Raw Blame History

Наборы и диапазоны [...]

Если в регулярном выражении нескольки символов или символьных классов заключены в квадратные скобки […], то это означает "искать любой символ из указанных в […]".

Например, [еао] означает любой символ из этих трёх: 'а', 'е', или 'о'. [cut] Можно использовать квадратные скобки вместе с обычными символами.

Например:

//+ run
// найти [г или т], а затем "оп"
alert( "Гоп-стоп".match( /[гт]оп/gi ) ); // "Гоп", "топ"

Несмотря на то, что в квадратных скобках несколько символов, в совпадении должен присутствовать ровно один из них.

Поэтому в примере ниже нет результатов:

//+ run
// найти "В", затем [у или а], затем "ля"
alert( "Вуаля".match( /В[уа]ля/ ) ); // совпадений нет

Совпадение было бы, если бы после "Ву" шло сразу "ля", например Вуля или если бы "Ва" сопровождалось "ля", то есть Валя.

Квадратные скобки могут также содержать диапазоны символов.

Например, [a-z] -- произвольный символ от a до z, [0-5] -- цифра от 0 до 5.

В примере ниже мы будем искать "x", после которого идёт два раза [0-9A-F] -- цифра или буква от A до F:

//+ run
// найдёт "xAF"
alert( "Exception 0xAF".match(/x[0-9A-F][0-9A-F]/g) );

Обратим внимание, в слове Exception есть сочетание xce, но оно не подошло, потому что буквы в нём маленькие, а в диапазоне -- большие.

Если хочется искать и его тоже, можно добавить в скобки диапазон 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 ) ); // "@", "."

В квадратных скобках большинство специальных символов можно использовать без экранирования.

Обычно, если мы хотим искать именно точку, а не любой символ, или именно "\d", а не произвольную цифру, то мы используем экранирование: указываем \. или \\d.

Но квадратные скобки подразумевают поиск одного символа из нескольких или из диапазона. Использование некоторых специальных символов внутри них не имело бы смысла, и они воспринимаются как обычные символы.

Это касается символов:

  • точка '.'
  • плюс '+'
  • круглые скобки '( )'
  • дефис '-', если он находится в начале или конце квадратных скобок, то есть не выделяет диапазон.
  • символ каретки '^', если не находится в начале квадратных скобок, то есть кроме [\^..].
  • а также открывающая квадратная скобка '['

То есть, точка "." в квадратных скобках означает не "любой символ", а обычную точку.

Например, регэксп [-().^+] ищет один из символов -().^. В данном контексте эти символы не являются специальными.

//+ run
var re = /[-().^+]/g;

alert( "1 + 2 - 3".match(re) ); // найдёт +, -

...Впрочем, даже если вы решите "на всякий случай" заэкранировать эти символы, поставив перед ними обратный слэш \ -- вреда не будет:

//+ run
var re = /[\-\(\)\.\^\+]/g;

alert( "1 + 2 - 3".match(re) ); // тоже работает: +, -