Регулярные выражения

для Epic Skills

Регулярные выражения

Создаём регулярку

Регулярка – тип объекта. Её можно создать, вызвав конструктор RegExp, или написав нужный шаблон, окружённый слешами.

var re1 = new RegExp(pattern, flags);
var re2 = /pattern/flags;

pattern - что искать, flags - как искать.
Аргумент flags — не обязательный.

Создаём регулярку

Например

var re1 = new RegExp("abc");
var re2 = /abc/;

Оба этих регулярных выражения представляют один шаблон: символ “a”, за которым следует символ “b”, за которым следует символ “c”.

Цифры

var re1 = /[0123456789]/;
var re2 = /[0-9]/;

В квадратных скобках тире между двумя символами используется для задания диапазона символов, где последовательность задаётся кодировкой Unicode. Символы от 0 до 9 находятся там просто подряд (коды с 48 до 57), поэтому [0-9] захватывает их все и совпадает с любой цифрой.

Любое слово на русском

var re1 = new RegExp("^[А-Яа-яЁё]+$");
var re2 = /^[А-Яа-яЁё]+$/;

Что может содержать регулярка

Сокращения групп символов

У нескольких групп символов есть свои встроенные сокращения.

\d Любая цифра
\w Алфавитно-цифровой символ
\s Пробельный символ (пробел, табуляция, перевод строки, и т.п.)
\D не цифра
\W не алфавитно-цифровой символ
\S не пробельный символ
. любой символ, кроме перевода строки

regex101.com

Начало и конец строки

В регулярке мы можем жёстко привязать проверку
к началу ^ или концу $ строки.

var rePhoneNumber = /^\+7/;
var reGmail = /gmail.com$/;

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

Любой из символов

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

var re = /[0-9]/;

Внутри квадратных скобок точка теряет своё особое значение и превращается просто в точку. То же касается и других специальных символов, типа +.

Любые символы кроме группы символов

Инвертировать набор символов – то есть, сказать, что вам надо найти любой символ, кроме тех, что есть в наборе – можно, поставив знак ^ сразу после открывающей квадратной скобки.

var re = /[^0-9]/;

Повторение части шаблона

Мы знаем, как найти один символ. А если нам надо найти последовательность из одного или более символов, подходящих под условие?

Если поставить после чего-либо в регулярке знак +, это будет означать, что этот элемент может быть повторён более одного раза. /\d+/ означает одну или несколько цифр.

/\d+/

Повторение части шаблона

У звёздочки * значение почти такое же, но она разрешает шаблону присутствовать ноль раз. Если после чего-то стоит звёздочка, то оно никогда не препятствует нахождению шаблона в строке – оно просто находится там ноль раз.

/\d*/

Необязательная часть шаблона

Знак вопроса делает часть шаблона необязательной, то есть она может встретиться ноль или один раз. Следующая регулярка пропустит и целое и дробное число (отделённое запятой).

var reNumber = /\d+(,\d+)?/

Заданное количество символов

Чтобы задать точное количество раз, которое шаблон должен встретиться, используются фигурные скобки.
{4} после элемента означает, что он должен встретиться в строке 4 раза.

Также можно задать промежуток: {2,4} означает, что элемент должен встретиться не менее 2 и не более 4 раз.

var reDateTime =
/\d{1,2}-\d{1,2}-\d{4} \d{1,2}:\d{2}/;

Заданное количество символов

Можно использовать промежутки, опуская одно из чисел.
{,5} означает, что шаблон может встретиться до пяти раз, а {5,} – от пяти.

var reUserName = /[A-Za-z]{6,}/;
var reSmsCode = /[0-9]{,3}/;

Группировка подвыражений

Чтобы использовать операторы * или + на нескольких элементах сразу, можно использовать круглые скобки. Часть регулярки, заключённая в скобки, считается одним элементом с точки зрения операторов.

var reEmail = /^([a-z0-9_.-]+)@([a-z0-9_.-]+)\.([a-z.]{2,6})$/;
var reDate = /^((0?[1-9]|1[012])[- \/.](0?[1-9]|[12][0-9]|3[01])[- \/.](19|20)?[0-9]{2})*$/;

Захватывающие скобки

Можно найти и запомнить сопоставление с частью подстроки.

/(foo)/ - находит подстроку «foo» и запоминает её в строке «foo bar». Найденную подстроку можно достать из элементов результирующего массива.

Аккуратнее! Захват групп ведёт к проседанию производительности. Если вам не нужно повторно ссылаться на захваченную подстроку, лучше использовать скобки без захвата.

Скобки без захвата

Если в захваченную подстроку дописать вначале ?:, то она не будет доступна в результирующем массиве.

/(?:foo)/ - лишь находит подстроку «foo» в строке «foo bar», но не сохраняет.

Шаблоны с выбором

Иногда в регулярке требуется проверить два или более вариантов сочетаний символов.

Можно было бы написать три регулярки и проверить их по очереди, но есть способ лучше. Символ | обозначает выбор между шаблонами слева и справа от него. И можно сказать следующее:

/(cat|dog|fox)/

Флаги

Мы можем указывать, каким образом искать вхождения

g глобальное сопоставление
i игнорирование регистра при сопоставлении
m cопоставление по нескольким строкам; символы начала и конца (^ и $) начинают работать по нескольким строкам (то есть, происходит сопоставление с началом или концом каждой строки (строки разделяются символами \n или \r), а не только с началом или концом всей вводимой строки)

Блок-схемы

Чем больше условий - тем сложнее регулярка. В какой-то момент регулярки становятся настолько сложными, что без блок-схемы не разобраться.

Построить блок-схему

Методы регулярок

Проверяем на совпадения: test

У регулярок есть несколько методов. Простейший – test. Если передать ему строку, он вернёт булевское значение, сообщая, содержит ли строка вхождение заданного шаблона.

/abc/.test("abcde"); //
/abc/.test("aabcd"); //
/abc/.test("abxde"); //
var re = /abc/; re.test("abxde"); //

search

Выяснить, содержит ли строка abc, можно было бы и при помощи indexOf. Регулярки же позволяют составлять более сложные шаблоны.

А вот indexOf нельзя использовать с регулярками. Зато метод search как раз ожидает регулярку. Как и indexOf, он возвращает индекс первого вхождения, или -1, если его не случилось.

"wor ld".search(/ /); //
"world".search(/ /); //

match

Метод match работает по-разному, в зависимости от наличия или отсутствия флага g.

Без флага g вернется массив, состоящий из этого совпадения, с дополнительными свойствами: index – позиция, на которой оно обнаружено и input – строка, в которой был поиск.

match

      var result = 'строка Строк'.match(/стр/gi);
      result[0]; // 
      result.index // 
      result.input // 
    

match

Если часть шаблона обозначена скобками, то она станет отдельным элементом массива.

      var result = 'строка Строк'.match(/стр/gi);
      result[0]; // 
      result[1]; // 
      result.index // 
      result.input // 
    

match

C флагом g вернется массив, состоящий только из совпадений, без доп. свойств.

      var result = 'строка Строк'.match(/стр/gi);
      result[0]; // 
      result.index // 
      result.input // 
    

exec

Eсть ещё метод exec, который вернёт null, если ничего не было найдено, а в противном случае вернёт объект с информацией о совпадении.

/100/g.exec("99..100")
/100/g.exec("100..100")

split

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

'12-34-56'.split('-'); //

'12-34-56'.split(/-/); //

replace

Есть метод replace, который может заменять часть строки другой строкой. Первый аргумент может быть и регуляркой, в таком случае заменяется первое вхождение регулярки в строке. Когда к регулярке добавляется опция “g” (global, всеобщий), заменяются все вхождения, а не только первое

При вызове со строкой замены replace всегда заменяет только первое совпадение. Для замены всех совпадений нужен флаг g

replace

"Borobudur".replace(/[ou]/, "a")

"Hopper, Grace\nMcCarthy, John\nRitchie, Dennis".replace(/([\w ]+), ([\w ]+)/g, "$2 $1")

"the cia and fbi".replace(/\b(fbi|cia)\b/g, function(str) {
  return str.toUpperCase();
});