var regexp = new RegExp("шаблон", "флаги");
// or
var regexp = /шаблон/; // без флагов
var regexp = /шаблон/gmi; // с флагами gmiСлеши "/" говорят JavaScript о том, что это регулярное выражение. Они играют здесь ту же роль, что и кавычки для обозначения строк.
i
Если этот флаг есть, то регэксп ищет независимо от регистра, то есть не различает между А и а.
g
Если этот флаг есть, то регэксп ищет все совпадения, иначе – только первое.
m
Многострочный режим.
Возвращает позицию первого совпадения или -1, если ничего не найдено.
var str = "Люблю регэкспы я, но странною любовью";
str.search( /лю/i ) // 0
str.search( /но/i ) // 18
str.search( /робот/i ) // 18Ограничение метода search – он всегда ищет только первое совпадение.
Находит только одно, первое совпадение. Результат вызова – это массив, состоящий из этого совпадения, с дополнительными свойствами index – позиция, на которой оно обнаружено и input – строка, в которой был поиск.
var str = "ОЙ-Ой-ой";
str.match( /ой/i ); // ["ОЙ", index: 0, input: "ОЙ-Ой-ой"]Если часть шаблона обозначена скобками, то она станет отдельным элементом массива.
var str = "javascript - это такой язык";
str.match( /JAVA(SCRIPT)/i ); // ["javascript", "script", index: 0, input: "javascript - это такой язык"]Возвращает обычный массив из всех совпадений. Никаких дополнительных свойств у массива в этом случае нет, скобки дополнительных элементов не порождают.
var str = "ОЙ-Ой-ой";
str.match( /ой/ig ); // ["ОЙ", "Ой", "ой"]
str.match( /йо/ig ); // null - нет совпаденийВ случае, если совпадений не было, match возвращает null
Обратите внимание, это важно – если match не нашёл совпадений, он возвращает не пустой массив, а именно null.
Это важно иметь в виду, чтобы не попасть в такую ловушку:
var str = "Ой-йой-йой";
// результат match не всегда массив!
str.match(/лю/gi).length // ошибка! нет свойства length у nullРазбивает строку в массив по разделителю – регулярному выражению regexp или подстроке substr.
'12-34-56'.split(/-/) // [12, 34, 56]Простейшее применение
// заменить дефис на двоеточие
'12-34-56'.replace("-", ":") // 12:34-56При вызове со строкой замены replace всегда заменяет только первое совпадение.
Чтобы заменить все совпадения, нужно использовать для поиска не строку "-", а регулярное выражение /-/g, причём обязательно с флагом g:
// заменить дефис на двоеточие
'12-34-56'.replace( /-/g, ":" ) // 12:34:56В строке для замены можно использовать специальные символы (здесь подробнее):
var str = "Василий Пупкин";
str.replace(/(Василий) (Пупкин)/, '$2, $1') // Пупкин, Василий
var str = "Василий Пупкин";
str.replace(/Василий Пупкин/, 'Великий $&!') // Великий Василий Пупкин!Для ситуаций, которые требуют максимально «умной» замены, в качестве второго аргумента предусмотрена функция.
"ОЙ-Ой-ой".replace(/ой/gi, function(match, (тут могут быть скобочные совпадения), offset, string) {
return 'Слоово ' + match + ' найденно на позиции ' + offset + ' в строке ' + string;
});Метод test проверяет, есть ли хоть одно совпадение в строке str. Возвращает true/false.
var str = "Люблю регэкспы я, но странною любовью";
/лю/i.test(str) // true
/помидор/i.test(str) // falseМетод ведёт себя по-разному, в зависимости от того, есть ли у регэкспа флаг g.
Если флага g нет, то regexp.exec(str) ищет и возвращает первое совпадение, является полным аналогом вызова str.match(reg).
Если флаг g есть, то вызов regexp.exec возвращает первое совпадение и запоминает его позицию в свойстве regexp.lastIndex. Последующий поиск он начнёт уже с этой позиции. Если совпадений не найдено, то сбрасывает regexp.lastIndex в ноль.
var str = 'Многое по JavaScript можно найти на сайте http://javascript.ru';
var regexp = /javascript/ig;
var result;
"Начальное значение lastIndex: " + regexp.lastIndex; // 0
while (result = regexp.exec(str)) { // когда нет совпадений, возвращает null
'Найдено: ' + result[0] + ' на позиции:' + result.index ; // 10, 49
'Свойство lastIndex: ' + regexp.lastIndex ; // 20, 59
}
'Конечное значение lastIndex: ' + regexp.lastIndex; // 0 регексп сброшен в нольПоиск с нужной позиции
Можно заставить regexp.exec искать сразу с нужной позиции, если поставить lastIndex вручную:
var str = 'Многое по JavaScript можно найти на сайте http://javascript.ru';
var regexp = /javascript/ig;
regexp.lastIndex = 40;
regexp.exec(str).index ; // 49, поиск начат с 40-й позицииДля поиска только одного совпадения:
- Найти позицию первого совпадения –
str.search(reg). - Найти само совпадение –
str.match(reg). - Проверить, есть ли хоть одно совпадение –
regexp.test(str)илиstr.search(reg) != -1. - Найти совпадение с нужной позиции –
regexp.exec(str), начальную позицию поиска задать вregexp.lastIndex.
Для поиска всех совпадений:
- Найти массив совпадений –
str.match(reg), с флагомg. - Получить все совпадения, с подробной информацией о каждом –
regexp.exec(str)с флагомg, в цикле. Для поиска-и-замены: : - Замена на другую строку или результат функции --str.replace(reg, str|func)Для разбивки строки на части: str.split(str|reg)
\d
Цифра, символ от 0 до 9.
\s
Пробельный символ, включая табы, переводы строки и т.п.
\w
Символ «слова», а точнее – буква латинского алфавита или цифра или подчёркивание '_'. Не-английские буквы не являются \w, то есть русская буква не подходит.
\b
Граница слова, обозначает не символ, а границу между символами. Граница имеет «нулевую ширину» в том смысле, что обычно символам регулярного выражения соответствуют символы строки, но не в этом случае.
"Hello, Java!".match(/\bJava\b/) // Java
"Hello, Javascript!".match(/\bJava\b/) // null\D
Не-цифра, то есть любой символ кроме \d, например буква.
\S
Не-пробел, то есть любой символ кроме \s, например буква.
\W
Любой символ, кроме \w, то есть не латинница, не подчёркивание, не цифра. В частности, русские буквы принадлежат этому классу.
\B
Проверка, обратная \b.
В регулярном выражении все символы имеют значение. Даже (и тем более) – пробелы.
В регулярном выражении, точка "." обозначает любой символ, кроме перевода строки:
var re = /CS.4/;
"CSS4".match(re) // найдено "CSS4"
"CS-4".match(re) // найдено "CS-4"
"CS 4".match(re) // найдено "CS 4" (пробел тоже символ)[ \ ^ $ . | ? * + ( )
Чтобы использовать специальный символ в качестве обычного, он должен быть экранирован.
Или, другими словами, перед символом должен быть обратный слэш '\'.
Например, [еао] означает любой символ из этих трёх: 'а', 'е', или 'о'.
Обратим внимание: несмотря на то, что в наборе указано несколько символов, в совпадении должен присутствовать ровно один из них.
// найти [г или т], а затем "оп"
alert( "Гоп-стоп".match(/[гт]оп/gi) ); // "Гоп", "топ"Например, [a-z] – произвольный символ от a до z, [0-5] – цифра от 0 до 5.
Символьные классы – всего лишь более короткие записи для диапазонов, в частности:
\d– то же самое, что[0-9],\w– то же самое, что[a-zA-Z0-9_],\s– то же самое, что[\t\n\v\f\r ]плюс несколько юникодных пробельных символов.
/[\wа-яё]+/giКвадратные скобки, начинающиеся со знака каретки: [^…] находят любой символ, кроме указанных.
Например:
[^аеуо]– любой символ, кроме'a','e','y','o'.[^0-9]– любой символ, кроме цифры, то же что\D.[^\s]– любой не-пробельный символ, то же что\S.
В квадратных скобках большинство специальных символов можно использовать без экранирования, если конечно они не имеют какой-то особый смысл именно внутри квадратных скобок.
- Точка
'.'. - Плюс
'+'. - Круглые скобки
'( )'. - Дефис
'-', если он находится в начале или конце квадратных скобок, то есть не выделяет диапазон. - Символ каретки
'^', если не находится в начале квадратных скобок. - А также открывающая квадратная скобка
'['.
…Впрочем, даже если вы решите «на всякий случай» заэкранировать эти символы, поставив перед ними обратный слэш \ – вреда не будет:
Количество повторений символа можно указать с помощью числа в фигурных скобках: {n} - квантификатор.
У него есть несколько подформ записи:
Регэксп \d{5} обозначает ровно 5 цифр, в точности как \d\d\d\d\d.
"Мне 12345 лет".match(/\d{5}/) // "12345"Для того, чтобы найти, например, числа размером от трёх до пяти знаков, нужно указать границы в фигурных скобках: \d{3,5}
"Мне не 12, а 1234 года".match(/\d{3,5}/) // "1234"Последнее значение можно и не указывать. Тогда выражение \d{3,} найдет числа, длиной от трех цифр:
"Мне не 12, а 1234 года".match(/\d{3,}/) // "1234"Означает «один или более», то же что {1,}.
Например, \d+ находит числа – последовательности из 1 или более цифр:
var str = "+7(903)-123-45-67";
str.match(/\d+/g) // 7,903,123,45,67Означает «ноль или один», то же что и {0,1}. По сути, делает символ необязательным.
Например, регэксп ou?r найдёт o, после которого, возможно, следует u, а затем r.:
var str = "Можно писать color или colour (британский вариант)";
str.match(/colou?r/g) // color, colourОзначает «ноль или более», то же что {0,}. То есть, символ может повторяться много раз или вообще отсутствовать.
Пример ниже находит цифру, после которой идёт один или более нулей:
"100 10 1".match(/\d0*/g) // 100, 10, 1Регэксп «десятичная дробь» (число с точкой внутри): \d+\.\d+
"0 1 12.345 7890".match(/\d+\.\d+/g) // 12.345Регэксп «открывающий или закрывающий HTML-тег без атрибутов»: /<\/?[a-z][a-z0-9]*>/i
"<h1>Привет!</h1>".match(/<\/?[a-z][a-z0-9]*>/gi) // <h1>, </h1>var reg = /".+"/g;
var str = 'a "witch" and her "broom" is one';
astr.match(reg) // "witch" and her "broom"Его можно включить, если поставить знак вопроса '?' после квантификатора, так что он станет таким: *? или +? или даже ?? для '?'.
Чтобы не возникло путаницы – важно понимать: обычно ? сам является квантификатором (ноль или один). Но если он стоит после другого квантификатора (или даже после себя), то обретает другой смысл – в этом случае он меняет режим его работы на ленивый.
Регэксп /".+?"/g находит отдельно witch и broom:
var reg = /".+?"/g;
var str = 'a "witch" and her "broom" is one';
str.match(reg) // witch, broomЛенивость распространяется только на тот квантификатор, после которого стоит ?
Прочие квантификаторы остаются жадными.
"123 456".match(/\d+ \d+?/g) // 123 4Во втором случаем он находит только одно число, потому что Ленивый режим без необходимости лишний раз квантификатор не повторит.
В данном конкретном случае, возможно искать строки в кавычках, оставаясь в жадном режиме, с использованием регулярного выражения "[^"]+":
var reg = /"[^"]+"/g;
var str = 'a "witch" and her "broom" is one';
str.match(reg) // witch, broomЭта логика ни в коей мере не заменяет ленивые квантификаторы!
Она просто другая. И то и другое бывает полезно.
'Gogogo now!'.match(/(go)+/i) // "Gogogo"Без скобок, шаблон /go+/ означал бы g, после которого идёт одна или более o, например: goooo. А скобки «группируют» (go) вместе.
Скобки нумеруются слева направо.
При поиске методом String#match в результирующем массиве будет сначала всё совпадение, а далее – скобочные группы. Но метод выдаёт скобочные группы только при поиске без флага /.../g.
Для того, чтобы искать и с флагом /.../g и со скобочными группами, используется метод RegExp#exec:
// Метод String#match
var str = '<h1>Привет, мир!</h1>';
var reg = /<(.*?)>/;
str.match(reg) // массив: <h1>, h1
// Метод RegExp#exec
var str = '<h1>Привет, мир!</h1>';
var reg = /<(.*?)>/g;
var match;
while ((match = reg.exec(str)) !== null) {
// сначала выведет первое совпадение: <h1>,h1
// затем выведет второе совпадение: </h1>,/h1
match;
}var str = '<span class="my">';
var reg = /<(([a-z]+)\s*([^>]*))>/;
str.match(reg) // <span class="my">, span class="my", span, class="my"На нулевом месте – всегда совпадение полностью, далее – группы. Нумерация всегда идёт слева направо, по открывающей скобке.
Даже если скобочная группа необязательна и не входит в совпадение, соответствующий элемент массива существует (и равен undefined).
var match = 'ack'.match(/a(z)?(c)?/)
match.length // 3
match[0] // ac, всё совпадение
match[1] // undefined, для (z)? ничего нет
match[2] // cСкобочную группу можно исключить из запоминаемых и нумеруемых, добавив в её начало ?:.
var str = "Gogo John!";
var reg = /(?:go)+ (\w+)/i;
var result = str.match(reg);
result.length // 2
result[0] // Gogo John
result[1] // John - Gogo был проигнорированСкобочные группы можно не только получать в результате, но и использовать как в самом паттерне, так и в строке замены.
Ссылки в строке замены имеют вид $n, где n – это номер скобочной группы.
var name = "Александр Пушкин";
name.replace(/([а-яё]+) ([а-яё]+)/i, "$2, $1"); // Пушкин, Александрvar str = "He said: \"She's the one!\".";
var reg = /(['"])(.*?)\1/g;
str.match(reg) // "She's the one!"Теперь работает верно! Движок регулярных выражений, найдя первое скобочное выражение – кавычку (['"]), запоминает его и далее \1 означает «найти то же самое, что в первой скобочной группе».
Обратим внимание на два нюанса:
- Чтобы использовать скобочную группу в строке замены – нужно использовать ссылку вида
$1, а в шаблоне – обратный слэш:\1. - Чтобы в принципе иметь возможность обратиться к скобочной группе – не важно откуда, она не должна быть исключена из запоминаемых при помощи
?:. Скобочные группы вида(?:...)не участвуют в нумерации.
Альтернация обозначается символом вертикальной черты | и позволяет выбирать между вариантами
var reg = /html|php|css|java(script)?/gi
var str = "Сначала появился HTML, затем CSS, потом JavaScript"
str.match(reg) // 'HTML', 'CSS', 'JavaScript'В отличии от gr[ae]y, который позволяет выбирать посимвольно (найдёт gray, либо grey). Альтернация работает на уровне фраз и подвыражений, например: before(XXX|YYY)after будет искать beforeXXXafter или beforeYYYafter
Знак каретки ^ и доллара $ имеют в регулярном выражении особый смысл. Их называют «якорями» (anchor – англ.).
Каретка ^ совпадает в начале текста, а доллар $ – в конце.
Якоря являются не символами, а проверками.
Без якорей, regexp найдет все числа
var str = '100500 попугаев съели 500100';
str.match(/\d+/ig) // 100500, 500100 (нашло все числа)С кареткой ^:
str.match(/^\d+/ig) // 100500 (только в начале строки)Со знаком доллара $:
str.match(/\d+$/ig) // 500100Оба якоря используют одновременно, если требуется, чтобы шаблон охватывал текст с начала и до конца.
Например поиск дроби, и ничего другого
var num = "ля-ля 12.34";
num.match(/^\d+\.\d+$/ig) // null, не дробь
var num = "12.34";
num.match(/^\d+\.\d+$/ig) // 12.34, дробь!В мультистрочном режиме /***/m:
- Символ
^означает начало строки. - Символ
$означает конец строки.