en.javascript.info/10-regular-expressions-javascript/3-regexp-character-classes/article.md
2015-03-06 17:10:55 +03:00

10 KiB
Raw Blame History

Классы и спецсимволы

Рассмотрим практическую задачу -- есть телефонный номер "+7(903)-123-45-67", и нам нужно найти в этой строке цифры. А остальные символы нас не интересуют.

Для поиска символов определённого вида в регулярных выражениях предусмотрены "классы символов".

[cut]

Класс символов -- это специальное обозначение, под которое подходит любой символ данного класса.

Например, класс "любая цифра" обозначается \d. Это обозначение вставляется в паттерн наравне с остальными символами, и при поиске под него подходит любая цифра.

Регулярное выражение /\d/ ищет ровно одну цифру (первую):

//+ run
var str = "+7(903)-123-45-67";

var reg = /\d/;

alert( str.match(reg) ); // 7

...Ну а для поиска всех цифр достаточно добавить к нему флаг g:

//+ run
var str = "+7(903)-123-45-67";

var reg = /\d/g;

alert( str.match(reg) ); // массив цифр: 7,9,0,3,1,2,3,4,5,6,7

Важнейшие классы

Это был класс для цифр.

Конечно же, есть и другие. Самые полезные классы:

`\d` (от английского "digit" - "цифра")
Цифра, символ от `0` до `9`.
`\s` (от английского "space" - "пробел")
Пробельный символ, включая табы, переводы строки и т.п.
`\w` (от английского "word" -- "слово")
Символ латинского алфавита или цифра или подчёркивание `'_'`. Не-английские буквы не являются `\w`.

Регулярное выражение как правило содержит одновременно и обычные символы и классы.

Например, CSS\d найдёт строку CSS, с любой цифрой после неё.

Пример ниже найдёт строку CSS с любой цифровой версией:

//+ run
var str = "Стандарт CSS4 - это здорово";
var reg = /CSS\d/

alert( str.match(reg) ); // CSS4

Можно указать и несколько классов в одном регэкспе:

//+ run
alert( "Я люблю HTML5!".match(/\s\w\w\w\w\d/) ); // 'HTML5'

Совпадение (каждому классу в регэкспе соответствует один символ результата):

Обратные классы

Для каждого символьного класса существует "обратный ему", представленный такой же, но заглавной буквой.

"Обратный" -- означает, что ему соответствуют все остальные символы, например:

`\D`
Не-цифра, то есть любой символ кроме `\d`, например буква.
`\S`
Не-пробел, то есть любой символ кроме `\s`, например буква.
`\W`
Любой символ, кроме `\w`, то есть не латинница, не подчёркивание, не цифра. В частности, русские буквы принадлежат этому классу.

В начале этой главы мы видели, как получить из телефона +7(903)-123-45-67 все цифры.

Первый способ -- найти все цифры через match(/\d/g), но есть и альтернативный -- найти все НЕцифры и удалить их из строки:

//+ run
var str = "+7(903)-123-45-67";

alert( str.replace(/\D/g, "") ); // 79031234567

Спецсимволы

Регулярное выражение может также содержать стандартные спецсимволы строк, такие как перевод строки \n, табуляцию \t и другие.

Отличить их от классов очень просто -- для классов зарезервированы другие буквы. Так что никакого конфликта здесь нет.

Пробелы

Обычно мы не обращаем внимание на пробелы. Для нашего взгляда строки 1-5 и 1 - 5 почти идентичны.

Но в регулярных выражениях пробел - такой же символ, как и другие.

Поиск ниже не сработает, так как не учитывает пробелы вокруг дефиса:

//+ run
alert(  "1 - 5".match (/\d-\d/) );  // null, нет совпадений!

Поправим это, добавив в регэксп пробелы:

//+ run
alert(  "1 - 5".match (/\d - \d/) );  // работает, пробелы вокруг дефиса

В регулярные выражения также не надо вставлять лишние пробелы. Все символы имеют значение:

//+ run
alert( "1-5".match( /\d - \d/ ) ); // null, так как в строке 1-5 нет пробелов

Класс точка

Особым классом символов является точка ".".

В регулярном выражении, точка "." обозначает любой символ, кроме перевода строки:

//+ run
alert( "Z".match(/./) ); // найдено Z

Посередине регулярного выражения:

//+ run
var re = /CS.4/;

alert( "CSS4".match(re) ); // найдено "CSS4"
alert( "CS-4".match(re) ); // найдено "CS-4" 
alert( "CS 4".match(re) ); // найдено "CS 4" (пробел тоже символ)

Обратим внимание -- точка означает именно "произвольный символ".

То есть какой-то символ на этом месте в строке должен быть:

//+ run
alert( "CS4".match (/CS.4/) ); // нет совпадений, так как для точки нет символа

Экранирование специальных символов

В регулярных выражениях есть и другие символы, имеющие особый смысл.

Они используются, чтобы расширить возможности поиска.

Вот их полный список: [ \ ^ $ . | ? * + ( ).

Не пытайтесь запомнить его -- когда мы разберёмся с каждым из них по отдельности, он запомнится сам собой.

Чтобы использовать специальный символ в качестве обычного, он должен быть экранирован.

Или, другими словами, перед символом должен быть обратный слэш '\'.

Например, нам нужно найти точку '.'. В регулярном выражении она означает "любой символ, кроме новой строки", поэтому чтобы найти именно сам символ "точка" -- её нужно экранировать: ..

//+ run
alert( "Глава 5.1".match( /\d\.\d/ ) );  // 5.1

Круглые скобки также являются специальными символами, так что для поиска именно скобки нужно использовать \(. Пример ниже ищет строку "g()":

//+ run
alert( "function g()".match( /g\(\)/ ) );  // "g()"

Сам символ слэш '/', хотя и не является специальными символом в регулярных выражениях, но открывает-закрывает регэксп в синтаксисе /...pattern.../, поэтому его тоже нужно экранировать.

Так выглядит поиск слэша '/':

//+ run
alert( "/".match( /\// ) );  // '/'

Ну и, наконец, если нам нужно найти сам обратный слэш \, то его нужно просто задублировать.

Так выглядит поиск обратного слэша "\":

//+ run
alert( "1\2".match( /\\/ ) );  // '\'

Итого

Мы рассмотрели классы для поиска типов символов:

  • `\d` -- цифры.
  • `\D` -- не-цифры.
  • `\s` -- пробельные символы, переводы строки.
  • `\S` -- всё, кроме `\s`.
  • `\w` -- латинница, цифры, подчёркивание `'_'`.
  • `'.'` -- точка обозначает любой символ, кроме перевода строки.

Кроме того, в регэкспах допустимы и обычные спец-символы строк, например \n.

Если хочется поискать именно точку или какой-то другой "особый" символ, то его экранируют: .