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

Методы Javascript для работы с регулярными выражениями

В Javascript Существует 6 методов для работы с регулярными выражениями. Чаще всего мы будем использовать только половину из них.

Метод exec()

Метод RegExp, который выполняет поиск совпадения в строке. Он возвращает массив данных. Например:

var str = 'Some fruit: Banana - 5 pieces. For 15 monkeys.';

var re = /(\w+) - (\d) pieces/ig;
var result = re.exec(str);

window.console.log(result);

// result = 
// Так же мы можем посмотреть позицию совпадения - result.index

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

Метод test()

Метод RegExp, который проверяет совпадение в строке, возвращает либо true, либо false. Очень удобен, когда нам необходимо проверить наличие или отсутствие паттерна в тексте. Например:

var str = 'Balance: 145335 satoshi';

var re = /Balance:/ig;
var result = re.test(str);

window.console.log(result); // true

В данном примере, есть совпадение с паттерном, поэтому получаем true.

Метод search()

Метод String, который тестирует на совпадение в строке. Он возвращет индекс совпадения, или -1 если совпадений не будет найдено. Очень похож на метод indexOf() для работы со строками. Минус этого метода — он ищет только первое совпадение. Для поиска всех совпадений используйте метод match().

var str = "Умея автоматизировать процессы, можно зарабатывать миллионы";
window.console.log(str.search(/можно/igm)); // 60 
window.console.log(str.search(/атата/igm)); // -1

Метод match()

Метод String, который выполняет поиск совпадения в строке. Он возвращет массив данных либо null если совпадения отсутствуют.

// Без использования скобочных групп
var str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
var regexp = //gi;
var matches_array = str.match(regexp);

window.console.log(matches_array); // 

// С использованием скобочных групп без флага g
var str = 'Fruits quantity: Apple - 5, Banana - 7, Orange - 12. I like fruits.';

var found = str.match(/(\d{1,2})/i);
window.console.log(found); // Находит первое совпадение и возвращает объект
// {
// 0:		"5"	
// 1:		"5"	
// index:	25	
// input:	"Fruits quantity: Apple -...ge - 12. I like fruits."
// }

// С использованием скобочных групп с флагом g
var found = str.match(/(\d{1,2})/igm);
window.console.log(found); // 

Если совпадений нету — возвращает null.

Метод replace()

Метод String, который выполняет поиск совпадения в строке, и заменяет совпавшую подстроку другой подстрокой переданной как аргумент в этот метод. Мы уже использовали эту функцию для работы о строками, регулярные выражения привносят новые возможности.

// Обычная замена
var str = 'iMacros is awesome, and iMacros is give me profit!';
var newstr = str.replace(/iMacros/gi, 'Javascript');

window.console.log(newstr); // Javascript is awesome, and Javascript is give me profit!

// Замена, используя параметры. Меняем слова местами:
var re = /(\w+)\s(\w+)/;
var str = 'iMacros JS';
var newstr = str.replace(re, '$2, $1'); // в переменных $1 и $2 находятся значения из скобочных групп
window.console.log(newstr); // JS iMacros

У метода replace() есть очень важная особенность — он имеет свой каллбэк. То есть, в качестве аргумента мы можем подавать функцию, которая будет обрабатывать каждое найденное совпадение. 

Нестандартное применение метода replace():

var str = `
	I have some fruits:
	Orange - 5 pieces
	Banana - 7 pieces
	Apple - 15 pieces
	It's all.
`;
var arr = []; // Сюда складируем данные о фруктах и их количестве

var newString = str.replace(/(\w+) - (\d) pieces/igm, function (match, p1, p2, offset, string) {
	
	window.console.log(arguments);
	
	arr.push({
		name: p1,
		quantity: p2
	});

	return match;
});


window.console.log(newString);  // Текст не изменился, как и было задумано
window.console.log(arr);        // Мы получили удобный массив объектов, с которым легко и приятно работать

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

Обратите внимание на аргумент функции offset — это будет индекс начала совпадения, этот параметр нам потом пригодится. В нашем случае, мы имеем 2 скобочные группы в паттерне, поэтому у нас в функции 5 аргументов, но их там может быть и больше

Метод split()

Метод String, который использует регулярное выражение или фиксированую строку чтобы разбить строку на массив подстрок.

var str = "08-11-2016";

// Разбиваем строку по разделителю
window.console.log(str.split('-')); // 

// Такой же пример с регэкспом
window.console.log(str.split(/-/)); // 

Экранирование внутри […]

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

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

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

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

Точка внутри квадратных скобок – просто точка. Шаблон будет искать один из символов: точку или запятую.

В приведённом ниже примере регулярное выражение ищет один из символов :

…Впрочем, если вы решите экранировать «на всякий случай», то не будет никакого вреда:

Строковые методы, поиск и замена

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

Все методы, кроме replace, можно вызывать как с объектами типа regexp в аргументах, так и со строками, которые автоматом преобразуются в объекты RegExp.

Так что вызовы эквивалентны:

var i = str.search(/\s/)
var i = str.search("\\s")

При использовании кавычек нужно дублировать \ и нет возможности указать флаги. Если регулярное выражение уже задано строкой, то бывает удобна и полная форма

var regText = "\\s"
var i = str.search(new RegExp(regText, "g"))

Возвращает индекс регулярного выражения в строке, или -1.

Если Вы хотите знать, подходит ли строка под регулярное выражение, используйте метод (аналогично RegExp-методы ). Чтобы получить больше информации, используйте более медленный метод (аналогичный методу ).

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

function testinput(re, str){
   if (str.search(re) != -1)
      midstring = " contains ";
   else
      midstring = " does not contain ";
   document.write (str + midstring + re.source);
}

Если в regexp нет флага , то возвращает тот же результат, что .

Если в regexp есть флаг , то возвращает массив со всеми совпадениями.

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

Если Вы хотите получить первый результат — попробуйте r.

В следующем примере используется, чтобы найти «Chapter», за которой следует 1 или более цифр, а затем цифры, разделенные точкой. В регулярном выражении есть флаг , так что регистр будет игнорироваться.

str = "For more information, see Chapter 3.4.5.1";
re = /chapter (\d+(\.\d)*)/i;
found = str.match(re);
alert(found);

Скрипт выдаст массив из совпадений:

  • Chapter 3.4.5.1 — полностью совпавшая строка
  • 3.4.5.1 — первая скобка
  • .1 — внутренняя скобка

Следующий пример демонстрирует использование флагов глобального и регистронезависимого поиска с . Будут найдены все буквы от А до Е и от а до е, каждая — в отдельном элементе массива.

var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var regexp = //gi;
var matches = str.match(regexp);
document.write(matches);

// matches = 

Метод replace может заменять вхождения регулярного выражения не только на строку, но и на результат выполнения функции. Его полный синтаксис — такой:

var newString = str.replace(regexp/substr, newSubStr/function)
Объект RegExp. Его вхождения будут заменены на значение, которое вернет параметр номер 2
Строка, которая будет заменена на .
Строка, которая заменяет подстроку из аргумента номер 1.
Функция, которая может быть вызвана для генерации новой подстроки (чтобы подставить ее вместо подстроки, полученной из аргумента 1).

Метод не меняет строку, на которой вызван, а просто возвращает новую, измененную строку.

Чтобы осуществить глобальную замену, включите в регулярное выражение флаг .

Если первый аргумент — строка, то она не преобразуется в регулярное выражение, так что, например,

var ab = "a b".replace("\\s","..") // = "a b"

Вызов replace оставил строку без изменения, т.к искал не регулярное выражение , а строку «\s».

В строке замены могут быть такие спецсимволы:

Pattern Inserts
Вставляет «$».
Вставляет найденную подстроку.
Вставляет часть строки, которая предшествует найденному вхождению.
Вставляет часть строки, которая идет после найденного вхождения.
or Где или — десятичные цифры, вставляет подстроку вхождения, запомненную -й вложенной скобкой, если первый аргумент — объект RegExp.

Если Вы указываете вторым параметром функцию, то она выполняется при каждом совпадении.

В функции можно динамически генерировать и возвращать строку подстановки.

Первый параметр функции — найденная подстрока. Если первым аргументом является объект , то следующие параметров содержат совпадения из вложенных скобок. Последние два параметра — позиция в строке, на которой произошло совпадение и сама строка.

Например, следующий вызов возвратит XXzzzz — XX , zzzz.

function replacer(str, p1, p2, offset, s)
{
return str + " - " + p1 + " , " + p2;
}
var newString = "XXzzzz".replace(/(X*)(z*)/, replacer)

Как видите, тут две скобки в регулярном выражении, и потому в функции два параметра , .
Если бы были три скобки, то в функцию пришлось бы добавить параметр .

Следующая функция заменяет слова типа на :

function styleHyphenFormat(propertyName)
{
  function upperToHyphenLower(match)
  {
    return '-' + match.toLowerCase();
  }
  return propertyName.replace(//, upperToHyphenLower);
}

Полезные методы работы с регулярными выражениями в JavaScript

Регулярные выражения, создаваемые с использованием флагов и последовательностей символов, которые мы обсуждали ранее в этой статье, предназначены для использования с различными методами JavaScript для поиска, замены или разделения строк.

Вот некоторые методы, связанные с регулярными выражениями.

► test() – проверяет, содержит ли основная строка подстроку, которая соответствует шаблону, заданному данным регулярным выражением. При успешном совпадении метод возвращает true, в противном случае — false.

JavaScript

	var textA = 'I like APPles very much';
	var textB = 'I like APPles';
	var regexOne = /apples$/i 
	// вернет false
	console.log(regexOne.test(textA)); 
	// вернет true
	console.log(regexOne.test(textB));

В приведённом выше примере приведено регулярное выражение, предназначенное для поиска слова “apples” в случае, если оно расположено в конце строки. Поэтому в первом случае метод вернет false.

► search() – проверяет, содержит ли основная строка подстроку, которая соответствует шаблону, заданному данным регулярным выражением. Метод возвращает индекс совпадения при успехе и -1 в противном случае.

JavaScript

	var textA = 'I like APPles very much';
	var regexOne = /apples/;
	var regexTwo = /apples/i; 
	// Результат: -1
	console.log(textA.search(regexOne)); 
	// Результат: 7
	console.log(textA.search(regexTwo));

В данном примере проверка по превому регулярному выражению вернет -1, потому что не указан флаг нечувствительности к регистру.

► match() – осуществляет поиск подстроки в основной строке. Подстрока должна соответствовать шаблону, заданному данным регулярным выражением. Если используется флаг g, то несколько совпадений будут возвращены в виде массива.

JavaScript

	var textA = 'All I see here are apples, APPles and apPleS';
	var regexOne = /apples/gi;
	 
	// Результат: 
	console.log(textA.match(regexOne));

► exec() – производит поиск подстроки в основной строке. В случае, если подстрока соответствует шаблону, заданному данным регулярным выражением, возвращает массив с результатами или null. В свойстве input хранится оригинальная строка

JavaScript

	var textA = 'Do you like apples?';
	var regexOne = /apples/; 
	// Результат: apples
	console.log(regexOne.exec(textA));
	 
	// Результат : Do you like apples?
	console.log(regexOne.exec(textA).input);

► replace() – ищет подстроку, соответствующую заданному шаблону и заменяет ее на предоставленную заменяющую строку.

JavaScript

	var textA = 'Do you like aPPles?';
	var regexOne = /apples/i
	 
	// Результат: Do you like mangoes?
	console.log(textA.replace(regexOne, 'mangoes'));

► split() – Этот метод позволит вам разбить основную строку на подстроки на основе разделителя, представленного в виде регулярного выражения.

JavaScript

	var textA = 'This 593 string will be brok294en at places where d1gits are.';
	var regexOne = /\d+/g
	 
	// Результат :  
	console.log(textA.split(regexOne))

Примеры

Разберём скобки на примерах.

Без скобок шаблон означает символ и идущий после него символ , который повторяется один или более раз. Например, или .

Скобки группируют символы вместе. Так что означает , , и т.п.

Сделаем что-то более сложное – регулярное выражение, которое соответствует домену сайта.

Например:

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

На языке регулярных выражений :

Поиск работает, но такому шаблону не соответствует домен с дефисом, например, , так как дефис не входит в класс .

Можно исправить это, заменим на везде, кроме как в конце: .

Итоговый шаблон:

Алгоритм[править]

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

— один любой буквенный символ,
— один любой символ,
— символ начала текста,
— символ конца текста,
— предыдущий символ встречается ноль или более раз.

Например, для , очевидно, проще написать простой сопоставитель, чем строить НКА.

Псевдокодправить

function match(regexp: String, text: String): boolean  
    if regexp == '^'
        return matchHere(regexp, text)  
    int i = 0
    while i  text.length
        if matchHere(regexp, text)
            return true
        i++
    return false

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

Логика функции проста. Если — первый символ регулярного выражения, то любое возможное вхождение должно начинаться в начале текста. То есть если — регулярное выражение, то должно входить в текст только с первой позиции текста, а не где-то в середине текста. Это проверяется путем сопоставления остатка регулярного выражения с текстом, начиная с первой позиции и нигде более.

В противном случае регулярное выражение может входить в текст в любой позиции. Это проверяется путем сопоставления регулярного выражения во всех позициях текста. Если регулярное выражение входит более одного раза в текст, то только самое левое вхождение будет распознано. То есть если — регулярное выражение, то для него найдется самое левое вхождение в текст.

function matchHere(regexp: String, text: String): boolean 
    if regexp == '\0'
        return true 
    if regexp == '*'  
        return matchStar(regexp, regexp, text)
    if regexp == '$' and regexp == '\0'
        return text == '\0'
    if text != '\0' and (regexp == '.' or regexp == text)
        return matchHere(regexp, text)
    return false

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

function matchStar(c: char, regexp: String, text: String): boolean
    int i = 0
    while i  text.length and (text == c or c == '.')
        if matchHere(regexp, text)
            return true
        i++
    return false

Рассмотрим возможные случаи:

  1. Если в ходе рекурсии регулярное выражение осталось пустым то текст допускается этим регулярным выражением.
  2. Если регулярное выражение имеет вид , то вызывается функция которая пытается сопоставить повторение символа , начиная с нуля повторений и увеличивая их количество, пока не найдет совпадение с оставшимся текстом. Если совпадение не будет найдено, то регулярное выражение не допускает текст. Текущая реализация ищет «кратчайшее совпадение», которое хорошо подходит для сопоставления с образцом, как в grep, где нужно как можно быстрее найти совпадение. «Наидлиннейшее совпадение» более интуитивно и больше подходит для текстовых редакторов, где найденное заменят на что-то. Большинство современных библиотек для работы с регулярными выражениями предоставляют оба варианта.
  3. Если регулярное выражение это , то оно допускает этот текст тогда и только тогда, когда текст закончился.
  4. Если первый символ текста совпал с первым символом регулярного выражения, то нужно проверить совпадают ли следующий символ регулярного выражения со следующим символом текста, сделав рекурсивный вызов .
  5. Если все предыдущие попытки найти совпадения провалились, то никакая подстрока из текста не допускается регулярным выражением.

Модификацииправить

Немного изменим функцию для поиск самого левого и самого длинного вхождения :

  1. Найдем максимальную последовательность подряд идущих символов . Назовем ее .
  2. Сопоставим часть текста без с остатком регулярного выражения.
  3. Если части совпали, то текст допускается этим регулярным выражением. Иначе, если пусто, то текст не допускается этим регулярным выражением, иначе убираем один символ из и повторяем шаг .

Псевдокодправить

function matchStar(c: char, regexp: String, text: String): boolean
    int i
    for (i = 0; text != '\0' and (text == c or c == '.'); i++)
    while i  0
        if matchHere(regexp, text)
            return true
        i--
    return false

Пример

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

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

Проверим, чтобы убедиться, что оно работает:

Результат верный. Однако, на некоторых строках оно выполняется очень долго. Так долго, что интерпретатор JavaScript «зависает» с потреблением 100% процессора.

Если вы запустите пример ниже, то, скорее всего, ничего не увидите, так как JavaScript «подвиснет»

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

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

Точка и перенос строки

Для поиска в многострочном режиме почти все модификации перловых регэкспов используют специальный multiline-флаг.

И javascript здесь не исключение.

Попробуем же сделать поиск и замену многострочного вхождения. Скажем, будем заменять на тэг подчеркивания: :

function bbtagit(text) {
  text = text.replace(/\(.*?)\[\/u\]/gim, '<u>$1</u>')
 
  return text
}

var line = "мой\n текст"
alert( bbtagit(line) )

Попробуйте запустить. Заменяет? Как бы не так!

Дело в том, что в javascript мультилайн режим (флаг ) влияет только на символы ^ и $, которые начинают матчиться с началом и концом строки, а не всего текста.

Точка по-прежнему — любой символ, кроме новой строки. В javascript нет флага, который устанавливает мультилайн-режим для точки. Для того, чтобы заматчить совсем что угодно — используйте .

Работающий вариант:

function bbtagit(text) {
  text = text.replace(/\(*)\[\/u\]/gim, '<u>$1</u>')
 
  return text
}

var line = "мой\n текст"
alert( bbtagit(line) )

Удаляем заглавные буквы с помощью строк и регулярных выражений

Теперь у нас есть строка с кучей ненужных прописных букв. Вы догадались, как их удалить? Во-первых, нам нужно выбрать все заглавные буквы. Затем используем поиск набора символов с помощью глобального модификатора //g. Мы снова будем использовать метод replace, но как в этот раз сделать строчной символ?

Пример:

Квадратные скобки задают диапазон символов (в данном случае — любые буквы английского алфавита в нижнем регистре). Все, что попадает в этот диапазон, будет соответствовать шаблону. Диапазоны символов могут быть разными. Это могут быть буквы в верхнем регистре (тогда диапазон будет выглядеть как ) или цифры ().

Если ваш диапазон должен охватывать все буквенно-цифровые символы и символ подчеркивания, то шаблон может выглядеть следующим образом: .

Backreferences в паттерне и при замене

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

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

Обращение к предыдущей части паттерна в javascript осуществляется как \1, \2 и т.п., бэкслеш + номер скобочной группы:

text = ' a b c  '

var reg = /\)\](.*?)\[\//*u*/\1/*/u*/\]/
text = text.replace(reg, '<$1>$2</$1>')
alert(text)

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

P.S. Понятно, что при таком способе поиска bb-тагов придется пропустить текст через замену несколько раз — пока результат не перестанет отличаться от оригинала.

Metacharacters

A metacharacter is simply an alphabetical character preceded by a backslash that acts to give the combination a special meaning.

For instance, you can search for a large sum of money using the ‘\d’ metacharacter: /(+)000/, Here \d will search for any string of numerical character.

The following table lists a set of metacharacters which can be used in PERL Style Regular Expressions.

Sr.No. Character & Description
1

.

a single character

2

\s

a whitespace character (space, tab, newline)

3

\S

non-whitespace character

4

\d

a digit (0-9)

5

\D

a non-digit

6

\w

a word character (a-z, A-Z, 0-9, _)

7

\W

a non-word character

8

a literal backspace (special case).

9

matches a single character in the given set

10

matches a single character outside the given set

11

(foo|bar|baz)

matches any of the alternatives specified

Quantifiers

The frequency or position of bracketed character sequences and single characters can be denoted by a special character. Each special character has a specific connotation. The +, *, ?, and $ flags all follow a character sequence.

Sr.No. Expression & Description
1

p+

It matches any string containing one or more p’s.

2

p*

It matches any string containing zero or more p’s.

3

p?

It matches any string containing at most one p.

4

p{N}

It matches any string containing a sequence of N p’s

5

p{2,3}

It matches any string containing a sequence of two or three p’s.

6

p{2, }

It matches any string containing a sequence of at least two p’s.

7

p$

It matches any string with p at the end of it.

8

^p

It matches any string with p at the beginning of it.

Examples

Following examples explain more about matching characters.

Sr.No. Expression & Description
1

It matches any string not containing any of the characters ranging from a through z and A through Z.

2

p.p

It matches any string containing p, followed by any character, in turn followed by another p.

3

^.{2}$

It matches any string containing exactly two characters.

4

<b>(.*)</b>

It matches any string enclosed within <b> and </b>.

5

p(hp)*

It matches any string containing a p followed by zero or more instances of the sequence hp.

test()

Для работы с регулярными выражениями есть несколько методов. Простейший из них —. При использовании этого метода необходимо передать функции проверяемую строку в качестве аргумента. В результате метод возвращает булево значение: — если в строке есть совпадения с шаблоном, — если совпадений нет.

// Синтаксис метода test()// /шаблон/.test('проверяемый текст')// Проверка строки,// когда test() не находит совпаденийmyPattern.test('There was a cat and dog in the house.')// false// Создание переменной,// которой присваивается текст для проверкиconst myString = 'The world of code.'// Создание шаблонаconst myPattern = /code/// Проверка текста с помощью шаблона,// когда test() находит совпадениеmyPattern.test(myString)// true

Создаем собственные регулярные выражения JavaScript

Существует два способа создания регулярного выражения: с использованием литерала регулярного выражения или с помощью конструктора регулярных выражений. Каждый из них представляет один и тот же шаблон: символ «c», за которым следует «a», а затем символ «t».

// литерал регулярного выражения заключается в слэши (/)
var option1 = /cat/;
// Конструктор регулярнго выражения 
var option2 = new RegExp("cat");

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

Содержимое скобок в match

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

Метод , если у регулярного выражения нет флага , ищет первое совпадение и возвращает его в виде массива:

  1. На позиции будет всё совпадение целиком.
  2. На позиции – содержимое первой скобочной группы.
  3. На позиции – содержимое второй скобочной группы.
  4. …и так далее…

Например, мы хотим найти HTML теги и обработать их. Было бы удобно иметь содержимое тега (то, что внутри уголков) в отдельной переменной.

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

Теперь получим как тег целиком , так и его содержимое в виде массива:

Скобки могут быть и вложенными.

Например, при поиске тега в нас может интересовать:

  1. Содержимое тега целиком: .
  2. Название тега: .
  3. Атрибуты тега: .

Заключим их в скобки в шаблоне: .

Вот их номера (слева направо, по открывающей скобке):

В действии:

По нулевому индексу в всегда идёт полное совпадение.

Затем следуют группы, нумеруемые слева направо, по открывающим скобкам. Группа, открывающая скобка которой идёт первой, получает первый индекс в результате – . Там находится всё содержимое тега.

Затем в идёт группа, образованная второй открывающей скобкой – имя тега, далее в будет остальное содержимое тега: .

Соответствие для каждой группы в строке:

Даже если скобочная группа необязательна (например, стоит квантификатор ), соответствующий элемент массива существует и равен .

Например, рассмотрим регулярное выражение . Оно ищет букву , за которой идёт необязательная буква , за которой, в свою очередь, идёт необязательная буква .

Если применить его к строке из одной буквы , то результат будет такой:

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

А теперь более сложная ситуация для строки :

Длина массива всегда равна . Для группы ничего нет, поэтому результат: .

Назад к словам и строкам

В начальном примере, когда мы ищем слова по шаблону в строке вида , происходит то же самое.

Дело в том, что каждое слово может быть представлено как в виде одного , так и нескольких:

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

Он перебирает все комбинации того, как регулярное выражение может «захватить» каждое слово, включая варианты как с пробелами , так и без (пробелы ведь не обязательны). Этих вариантов очень много, отсюда и сверхдолгое время выполнения.

Указание количества повторений символов в тексте

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

+ – Обозначает одно или более совпадение. Например, чтобы регулярное выражение совпало с набором символов “ABD12D” нужно использовать \w+.

* – Обозначает ноль или более символов. Например, под выражение b\w* подойдут следующие сочетания символов: “b”, “bat”, “bajhdsfbfjhbe”. В данном случае мы ищем соответствие нулевому или более количеству символов в словах после буквы “b”.

{m, n} – Соответствует не менее m и не более n вхождений предыдущего символа. {m,} будет соответствовать не менее, чем m вхождений, верхнего предела в этом случае нет. {k} будет соответствовать точному количеству (k) вхождений предыдущего символа.

? – Обозначает ноль или один символ. Например, это может быть полезно при сопоставлении двух вариантов написания для одной и той же слова. Выражению будут соответствовать оба слова: “behavior” и “behaviour”.

| – Соответствует выражению до или после символа |. Например, выражению /se(a|e)/ — соответсвуют оба слова: “see” и “sea”.

МетаСимволы

Для указания регулярных выражений используются метасимволы. В приведенном выше примере ( ) является метасимволом.

Метасимволы — это символы, которые интерпретируются особым образом механизмом RegEx. Вот список метасимволов:

[]. ^ $ * +? {} () \ |

— Квадратные скобки

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

Выражение Строка Совпадения
1 совпадение
2 совпадения
Не совпадает
5 совпадений

Здесь будет соответствовать, если строка, которую вы пытаетесь сопоставить, содержит любой из символов , или .

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

то же самое, что и .

то же самое, что и .

то же самое, что и .

Вы можете дополСтрока (инвертировать) набор символов, используя символ вставки в начале квадратной скобки.

означает любой символ, кроме или или .

означает любой нецифровой символ.

— Точка

Точка соответствует любому одиночному символу (кроме новой строки ).

Выражение Строка Совпадения
Не совпадает
1 совпадение
1 совпадение
2 совпадения (содержит 4 символа)

— Каретка

Символ каретки используется для проверки того, начинается ли строка с определенного символа.

Выражение Строка Совпадения
1 совпадение
1 совпадение
Не совпадает
1 совпадение
Нет совпадений (начинается с , но не сопровождается )

— доллар

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

Выражение Строка Совпадения
1 совпадение
1 совпадение
Не совпадает

— Звездочка

Символ звездочки соответствует предыдущему символу повторенному 0 или более раз. Эквивалентно {0,}.

Выражение Строка Совпадения
1 совпадение
1 совпадение
1 совпадение
Нет совпадений ( не следует )
1 совпадение

— Плюс

Символ плюс соответствует предыдущему символу повторенному 1 или более раз. Эквивалентно {1,}.

Выражение Строка Совпадения
Нет совпадений (нет символа)
1 совпадение
1 совпадение
Нет совпадений ( не следует )
1 совпадение

— Вопросительный знак

Знак вопроса соответствует нулю или одному вхождению предыдущего символа. То же самое, что и {0,1}. По сути, делает символ необязательным.

Выражение Строка Совпадения
1 совпадение (0 вхождений а)
1 совпадение
Нет совпадений (более одного символа)
Нет совпадений ( не следует )
1 совпадение

— Фигурные скобки

Рассмотрим следующий код: . Это означает, по крайней мере , и не больше повторений предыдущего символа. При m=n=1 пропускается..

Выражение Строка Совпадения
Не совпадает
1 совпадение (в )
2 совпадения (при и )
2 совпадения (при и )

Посмотрим еще один пример. Это RegEx соответствует как минимум 2 цифрам, но не более 4-х цифр.

Выражение Строка Совпадения
1 совпадение (совпадение в )
3 совпадения ( , , )
Не совпадает

— Альтернация (или)

Альтернация (вертикальная черта) – термин в регулярных выражениях, которому в русском языке соответствует слово «ИЛИ». (оператор ).

Например: gr(a|e)y означает точно то же, что и gry.

Выражение Строка Совпадения
Не совпадает
1 совпадение (совпадение в )
3 совпадения (в )

Здесь сопоставьте любую строку, содержащую либо, либо

Чтобы примеСтрока альтернацию только к части шаблона, можно заключить её в скобки:

  • найдёт или .
  • найдёт или .

— Скобочные группы

Круглые скобки используются для группировки подшаблонов. Так, например, соответствует любой строке, которая соответствует либо или или с последующим

Выражение Строка Совпадения
Не совпадает
1 совпадение (совпадение в )
2 совпадения (в )

— обратная косая черта

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

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

Если вы не уверены, имеет ли символ особое значение или нет, вы можете экранировать его косой чертой . Это гарантирует, что экранированный символ не будет компилироваться по-особенному.

Итого

Существуют следующие символьные классы:

  • – цифры.
  • – не цифры.
  • – пробельные символы, табы, новые строки.
  • – все, кроме .
  • – латиница, цифры, подчёркивание .
  • – все, кроме .
  • – любой символ, если с флагом регулярного выражения , в противном случае любой символ, кроме перевода строки .

…Но это не всё!

В кодировке Юникод, которую JavaScript использует для строк, каждому символу соответствует ряд свойств, например – какого языка это буква (если буква), является ли символ знаком пунктуации, и т.п.

Можно искать, в том числе, и по этим свойствам. Для этого нужен флаг , который мы рассмотрим в следующей главе.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector