Объект RegExp

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

Создание

var expr = new RegExp(pattern [, flags]); // полная форма записи

var expr = /pattern/flags;                // сокращенная форма записи (литеральный формат)

Параметры

pattern
Шаблон поиска (текст регулярного выражения).
flags
Способы поиска по шаблону:
  • g — глобальный поиск (обрабатываются все совпадения с шаблоном поиска);
  • i — не различать строчные и заглавные буквы;
  • m — многострочный поиск.
  • u — включает поддержку Юникода в регулярных выражениях.
Порядок указания флагов не имеет значения.

Комментарии

Когда регулярное выражение создается при помощи конструктора new RegExp(…), необходимо помнить, что обратные слеши (\) должны экранироваться, например:

var expr = new RegExp('\\w', 'ig');

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

var expr = /\w/gi;

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

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

Обычные символы

A..zанглийские буквы от A до z, строчные и заглавные
0..9цифры
{ }фигурные скобки, кроме случаев, когда они составляют группу вида {n,m} (где n и m — числа) и её вариации
=равно
<меньше
>больше
-минус
,запятая
и др. 

Специальные символы

( )круглые скобки
[ ]квадратные скобки
\обраный слеш
.точка
^степень
$знак доллара
|вертикальная черта
?вопросительный знак
+плюс.

Спецсимволы в регулярном выражении

СимволЗначение
\Для обычных символов - делает их специальными. Например, выражение /s/ ищет просто символ 's'. А если поставить \ перед s, то /\s/ уже обозначает пробельный символ. И наоборот, если символ специальный, например *, то \ сделает его просто обычным символом "звездочка". Например, /a*/ ищет 0 или больше подряд идущих символов 'a'. Чтобы найти а со звездочкой 'a*' - поставим \ перед спец. символом: /a\*/.
^Обозначает начало входных данных. Если установлен флаг многострочного поиска ("m"), то также сработает при начале новой строки. Например, /^A/ не найдет 'A' в "an A", но найдет первое 'A' в "An A."
$Обозначает конец входных данных. Если установлен флаг многострочного поиска, то также сработает в конце строки. Например, /t$/ не найдет 't' в "eater", но найдет - в "eat".
*Обозначает повторение 0 или более раз. Например, /bo*/ найдет 'boooo' в "A ghost booooed" и 'b' в "A bird warbled", но ничего не найдет в "A goat grunted".
+Обозначает повторение 1 или более раз. Эквивалентно {1,}. Например, /a+/ найдет 'a' в "candy" и все 'a' в "caaaaaaandy".
?Обозначает, что элемент может как присутствовать, так и отсутствовать. Например, /e?le?/ найдет 'el' в "angel" и 'le' в "angle."Если используется сразу после одного из квантификаторов *, +, ?, или {}, то задает "нежадный" поиск (повторение минимально возможное количество раз, до ближайшего следующего элемента паттерна), в противоположность "жадному" режиму по умолчанию, при котором количество повторений максимально, даже если следующий элемент паттерна тоже подходит. Кроме того, ? используется в предпросмотре, который описан в таблице под (?=), (?!), и (?: ).
.(Десятичная точка) обозначает любой символ, кроме перевода строки: \n \r \u2028 or \u2029. (можно использовать [\s\S] для поиска любого символа, включая переводы строк). Например, /.n/ найдет 'an' и 'on' в "nay, an apple is on the tree", но не 'nay'.
(x)Находит x и запоминает. Это называется "запоминающие скобки". Например, /(foo)/ найдет и запомнит 'foo' в "foo bar." Найденная подстрока хранится в массиве-результате поиска или в предопределенных свойствах объекта RegExp: $1, ..., $9. Кроме того, скобки объединяют то, что в них находится, в единый элемент паттерна. Например, (abc)* - повторение abc 0 и более раз.
(?:x)Находит x, но не запоминает найденное. Это называется "незапоминающие скобки". Найденная подстрока не сохраняется в массиве результатов и свойствах RegExp. Как и все скобки, объединяют находящееся в них в единый подпаттерн.
x(?=y)Находит x, только если за x следует y. Например, /Jack(?=Sprat)/ найдет 'Jack', только если за ним следует 'Sprat'. /Jack(?=Sprat|Frost)/ найдет 'Jack', только если за ним следует 'Sprat' или 'Frost'. Однако, ни 'Sprat' ни 'Frost' не войдут в результат поиска.
x(?!y)Находит x, только если за x не следует y. Например, /\d+(?!\.)/ найдет число, только если за ним не следует десятичная точка. /\d+(?!\.)/.exec("3.141") найдет 141, но не 3.141.
x|yНаходит x или y. Например, /green|red/ найдет 'green' в "green apple" и 'red' в "red apple."
{n}Где n - положительное целое число. Находит ровно n повторений предшествующего элемента. Например, /a{2}/ не найдет 'a' в "candy," но найдет оба a в "caandy," и первые два a в "caaandy."
{n,}Где n - положительное целое число. Находит n и более повторений элемента. Например, /a{2,} не найдет 'a' в "candy", но найдет все 'a' в "caandy" и в "caaaaaaandy."
{n,m}Где n и m - положительные целые числа. Находят от n до m повторений элемента.
[xyz]Набор символов. Находит любой из перечисленных символов. Вы можете указать промежуток, используя тире. Например, [abcd] - то же самое, что [a-d]. Найдет 'b' в "brisket" и 'c' в "ache".
[^xyz]Любой символ, кроме указанных в наборе. Вы также можете указать промежуток. Например, [^abc] - то же самое, что [^a-c]. Найдет 'r' в "brisket" и 'h' в "chop."
[\b]Находит символ backspace. (Не путать с \b.)
\bНаходит границу слов (латинских), например пробел. (Не путать с [\b]). Например, /\bn\w/ найдет 'no' в "noonday"; /\wy\b/ найдет 'ly' в "possibly yesterday."
\BОбозначает не границу слов. Например, /\w\Bn/ найдет 'on' в "noonday", а /y\B\w/ найдет 'ye' в "possibly yesterday."
\cXГде X - буква от A до Z. Обозначает контрольный символ в строке. Например, /\cM/ обозначает символ Ctrl-M.
\dнаходит цифру из любого алфавита (у нас же юникод). Используйте [0-9], чтобы найти только обычные цифры. Например, /\d/ или /[0-9]/ найдет '2' в "B2 is the suite number."
\DНайдет нецифровой символ (все алфавиты). [^0-9] - эквивалент для обычных цифр. Например, /\D/ или /[^0-9]/ найдет 'B' в "B2 is the suite number."
\f,\r,\nСоответствующие спецсимволы form-feed, line-feed, перевод строки.
\sНайдет любой пробельный символ, включая пробел, табуляцию, переводы строки и другие юникодные пробельные символы. Например, /\s\w*/ найдет ' bar' в "foo bar."
\SНайдет любой символ, кроме пробельного. Например, /\S\w*/ найдет 'foo' в "foo bar."
\tСимвол табуляции.
\vСимвол вертикальной табуляции.
\wНайдет любой словесный (латинский алфавит) символ, включая буквы, цифры и знак подчеркивания. Эквивалентно [A-Za-z0-9_]. Например, /\w/ найдет 'a' в "apple," '5' в "$5.28," и '3' в "3D."
\WНайдет любой не-(лат.)словесный символ. Эквивалентно [^A-Za-z0-9_]. Например, /\W/ и /[^$A-Za-z0-9_]/ одинаково найдут '%' в "50%."
\nгде n - целое число. Обратная ссылка на n-ю запомненную скобками подстроку. Например, /apple(,)\sorange\1/ найдет 'apple, orange,' в "apple, orange, cherry, peach.". За таблицей есть более полный пример.
\0Найдет символ NUL. Не добавляйте в конец другие цифры.
\xhhНайдет символ с кодом hh (2 шестнадцатиричных цифры)
\uhhhhНайдет символ с кодом hhhh (4 шестнадцатиричных цифры).

Пример изменения формата строки

var re = /(\w+)\s(\w+)/;
var str = "John Smith";
var newstr = str.replace(re, "$2, $1");
Alert(newstr); // "Smith, John"

Свойства

globalТестировать или нет регулярное выражение относительно всех возможных совпадений в строке, или только относительно первого совпадения.
ignoreCaseИгнорировать ли регистр при поиске совпадения в строке.
lastIndexИндекс, с которого начинается следующее совпадение.
multilineИскать ли на нескольких строках.
sourceТекст патэрна

Методы

execВыполняет поиск совпадения в своём строковом параметре.
testТестирует на совпадение в своём строковом параметре.

А также методы объекта String

matchВыполняет поиск совпадения в строке. Возвращает массив информации, или null при отсутствии совпадения.
searchТестирует на наличие совпадений в строке. Возвращает индекс совпадения или -1, если поиск завершился неудачно.
replaceВыполняет поиск совпадения в строке и заменяет найденные подстроки замещающей подстрокой.
splitИспользует регулярное выражение или фиксированную строку для разделения строки на массив подстрок.

global

Используется ли флаг "g" в регулярном выражении.

Синтаксис

regexp.global

Описание, комментарии, примеры

global это свойство отдельного объекта регулярного выражения.

Вы не можете изменять это свойство явно.

Значение global будет true, если флаг "g" используется; иначе - false. Флаг "g" указывает, что регулярное выражение должно проверяться относительно всех возможных совпадений в строке.

//Определим произвольное регулярное выражение
var regexp = /Шаблон пример/g;
/* В случае если regexp содержит модификатор g выведем 
"Модификатор g установлен", в противном случае выведем 
"Модификатор g не установлен" */
if (regexp.global)
Alert("Модификатор g установлен");
else
Alert("Модификатор g не установлен");

ignoreCase

Используется ли флаг "i" в регулярном выражении.

Синтаксис

regexp.ignoreCase

Описание, комментарии, примеры

ignoreCase это свойство отдельного объекта регулярного выражения.

Вы не можете изменять это свойство явно.

Значение ignoreCase будет true, если флаг "i" используется; иначе - false. Флаг "i" указывает, что регистр символов должен игнорироваться при поиске совпадений в строке.

//Определим произвольное регулярное выражение
var regexp = /Шаблон пример/i;
/* В случае если regexp содержит модификатор i выведем 
"Модификатор i установлен", в противном случае выведем 
"Модификатор i не установлен" */
if (regexp.ignoreCase)
Alert("Модификатор i установлен");
else
Alert("Модификатор i не установлен");

lastIndex

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

Синтаксис

regexp.lastIndex

Комментарии

Это свойство будет работать только если в регулярном выражении установлен модификатор g.

Данное свойство возвращает целое число, которое обозначает позицию последнего символа найденного с помощью метода exec или test.

Пример

//Определим произвольное регулярное выражение
var str = "Я короткая строка";
//Зададим регулярное выражение
var regexp = /о/g;
//Совершим глобальный поиск 'o' в строке текста и будем отображать
//позицию после каждого найденного совпадения
while (regexp.test(str)==true)
{
Alert( regexp.lastIndex );
}

multiline

Используется ли флаг "m" в регулярном выражении.

Синтаксис

regexp.global

Описание, комментарии, примеры

multiline это свойство отдельного объекта регулярного выражения.

Вы не можете изменять это свойство явно.

Значение multiline будет true, если флаг "g" используется; иначе - false. Флаг "g" указывает, что регулярное выражение должно проверяться относительно всех возможных совпадений в строке.

//Определим произвольное регулярное выражение
var regexp = /Шаблон пример/m;
/* В случае если regexp содержит модификатор g выведем 
"Модификатор g установлен", в противном случае выведем 
"Модификатор g не установлен" */
if (regexp.multiline)
Alert("Модификатор m установлен");
else
Alert("Модификатор g не установлен");

source

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

Синтаксис

regexp.source

Комментарии

Свойство "только для чтения", содержащее текст патэрна, исключая слэши (/) и флаги "g" и "i".

Вы не можете изменять это свойство явно.

Пример

//Определим произвольное регулярное выражение
var regexp = /Шаблон пример/g;
//Возвратим содержимое его шаблона
Alert(regexp.source);

exec

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

Синтаксис

regexp.exec(str)

Параметры

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

Возвращаемое значение

Если сопоставление успешно выполнилось, метод exec возвращает массив (array) и обновляет свойства объекта регулярного выражения (regexp):

Массив (array)
array[0] Сопоставленная подстрока
array[1], array[2], ...Сопоставившиеся подстроки в круглых скобках, если они присутствуют. Количество возможных подстрок ничем не ограничено.
array['index']Позиция символа, с которого начинается сопоставленная подстрока.
array['input']Исходная строка
Объект регулярного выражения (regexp):
reqexp.lastIndexИндекс начала следующего совпадения. Если отсутствует флаг "g", остаётся равным нулю.
reqexp.ignoreCaseУказывает, что в регулярном выражении используется флаг игнорирования регистра "i".
reqexp.globalУказывает, что в регулярном выражении используется флаг глобального сопоставления "g".
reqexp.multilineУказывает, что в регулярном выражении используется флаг сопоставления по нескольким строкам "m".
reqexp.sourceТекст шаблона регулярного выражения.

Если сопоставление не удалось, метод exec возвращает null.

Описание, комментарии, примеры

Метод exec ведёт себя по-разному, в зависимости от того, есть ли у регэкспа флаг "g":

var regexp = /th(..)/g;
var str = "something this";
while ( (arr=regexp.exec(str)) != null) {
 Alert( 
	"\narr[0] = " + arr[0] + 
	"\narr[1] = " + arr[1] + 
	"\narr['index'] = " +  arr.index + 
	"\narr['input'] = " + arr.input + 
	"\nregexp.lastIndex = " + regexp.lastIndex +
	"\nregexp.ignoreCase = " + regexp.ignoreCase +
	"\nregexp.global = " + regexp.global +
	"\nregexp.multiline = " + regexp.multiline +
	"\nregexp.source = " + regexp.source );
}

test

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

Синтаксис

regexp.test([str])

Параметры

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

Возвращаемое значение

Метод возвращает true если совпадения были найдены, и false если нет.

Комментарии

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

Чтобы получить сами совпадения - используйте exec или String#match.

Пример

//Зададим строку текста
var str = "Европа — одна из шести частей света.";
//Зададим регулярное выражение с шаблоном "Европа"
regexp = /Европа/;
//И регулярное выражение с шаблоном "Африка"
regexp2 = /Африка/;
//Проверим имеются ли совпадения между регулярными выражениями
//и строкой и отобразим результат 
Alert(
  regexp.test(str)+"\n"+
  regexp2.test(str));

Особенности регулярных выражений в Javascript

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

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

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

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

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

var line = "[u]мой\n текст[/u]"
Alert( bbtagit(line) );

Жадность

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

Например, мы хотим заменить все открывающие тэги <a>. На что и почему – не так важно.

var text = '1 <A href="#">...</A> 2'
text = text.replace(/<A(.*)>/, 'TEST')
Alert(text)

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

Это происходит из-за того, что точка-звездочка в «жадном» режиме пытается захватить как можно больше, в нашем случае – это как раз до последнего >.

Для переключение точки-звездочки в нежадный режим надо добавить знак «?» после звездочки.

В нежадном режиме точка-звездочка пустит поиск дальше сразу, как только нашла совпадение:

var text = '1 <A href="#">...</A> 2'
text = text.replace(/<A(.*?)>/, 'TEST')
Alert(text)

Юникод: флаг "u" и класс \p{...}

В JavaScript для строк используется кодировка Юникод. Обычно символы кодируются с помощью 2 байтов, что позволяет закодировать максимум 65536 символов.

Этого диапазона не хватает для того, чтобы закодировать все символы. Поэтому некоторые редкие символы кодируются с помощью 4 байтов, например 𝒳 (математический X) или 😄 (смайлик), некоторые иероглифы, и т.п.

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

СимволЮникодКоличество байт в Юникоде
a0x00612
0x22482
𝒳0x1d4b34
𝒴0x1d4b44
😄0x1f6044

Таким образом, символы типа a и занимают по 2 байта, а коды для 𝒳, 𝒴 и 😄 – длиннее, в них 4 байта.

Раньше на момент создания языка JavaScript, кодировка Юникод была проще: символов в 4 байта не существовало. И, хотя это время давно прошло, многие строковые функции всё ещё могут работать некорректно.

Например, свойство length считает, что здесь два символа:

Alert('😍'.length); // 2
Alert('𝒳'.length); // 2

…Но видно, что только один, верно? Дело в том, что свойство length воспринимает 4-байтовый символ как два символа по 2 байта. Это неверно, потому что эти два символа должны восприниматься как единое целое (так называемая «суррогатная пара».

Регулярные выражения также по умолчанию воспринимают 4-байтные «длинные символы» как пары 2-байтных. Как и со строками, это может приводить к странным результатам.

В отличие от строк, у регулярных выражений есть специальный флаг u, который исправляет эту проблему. При его наличии регулярное выражение работает с 4-байтными символами правильно. И, кроме того, становится доступным поиск по Юникодным свойствам.

Юникодные свойства \p{…}

Каждому символу в кодировке Юникод соответствует множество свойств. Они описывают к какой «категории» относится символ, содержат различную информацию о нём.

Например, свойство Letter у символа означает, что это буква какого-то алфавита, причём любого. А свойство Number означает, что это цифра: возможно, арабская или китайская, и т.д.

В регулярном выражении можно искать символ с заданным свойством, указав его в \p{…}. Для таких регулярных выражений обязательно использовать флаг u.

Например, \p{Letter} обозначает букву в любом языке. Также можно использовать запись \p{L}, так как L – это псевдоним Letter. Существуют короткие записи почти для всех свойств.

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

let str = "A ბ ㄱ";

Alert( str.match(/\p{L}/gu) ); // A,ბ,ㄱ
Alert( str.match(/\p{L}/g) ); // null (ничего не нашло, так как \p не работает без флага "u")

Вот основные категории символов и их подкатегории:

Буквы L
  • в нижнем регистре Ll,
  • модификаторы Lm,
  • заглавные буквы Lt,
  • в верхнем регистре Lu,
  • прочие Lo.
  • Числа N
  • десятичная цифра Nd,
  • цифры обозначаемые буквами (римские) Nl,
  • прочие No.
  • Знаки пунктуации P
  • соединители Pc,
  • тире Pd,
  • открывающие кавычки Pi,
  • закрывающие кавычки Pf,
  • открывающие скобки Ps,
  • закрывающие скобки Pe,
  • прочее Po.
  • Отметки M (например, акценты)
  • двоеточия Mc,
  • вложения Me,
  • апострофы Mn.
  • Символы S
  • валюты Sc,
  • модификаторы Sk,
  • математические Sm,
  • прочие So.
  • Разделители Z
  • линия Zl,
  • параграф Zp,
  • пробел Zs.
  • Прочие C
  • контрольные Cc,
  • форматирование Cf,
  • не назначенные Cn,
  • для приватного использования Co,
  • суррогаты Cs.
  • Так что, например, если нужны буквы в нижнем регистре, то можно написать \p{Ll}, знаки пунктуации: \p{P} и так далее.

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

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

    Пример: шестнадцатеричные числа

    Например, поиск шестнадцатеричного числа, записанные в формате xFF, где вместо F может быть любая шестнадцатеричная цифра (0…9 или A…F).

    Шестнадцатеричная цифра может быть обозначена как \p{Hex_Digit}:

    let regexp = /x\p{Hex_Digit}\p{Hex_Digit}/u;
    
    Alert("число: xAF".match(regexp)); // xAF
    

    Пример: китайские иероглифы

    В Юникоде есть свойство Script (система написания), которое может иметь значения Cyrillic (Кириллическая), Greek (Греческая), Arabic (Арабская), Han (Китайская) и так далее, здесь полный список.

    Для поиска символов в нужной системе мы должны установить Script=<значение>, например для поиска кириллических букв: \p{sc=Cyrillic}, для китайских иероглифов: \p{sc=Han}, и так далее:

    let regexp = /\p{sc=Han}/gu; // вернёт китайские иероглифы
    
    let str = `Hello Привет 你好 123_456`;
    
    Alert( str.match(regexp) ); // 你,好
    

    Пример: валют

    Символы, обозначающие валюты, такие как $, , ¥, имеют свойство \p{Currency_Symbol}, короткая запись: \p{Sc}.

    Используеся, чтобы поискать цены в формате «валюта, за которой идёт цифра»:

    let regexp = /\p{Sc}\d/gu;
    
    let  str = `Цены: $2, €1, ¥9`;
    
    Alert( str.match(regexp) ); // $2,€1,¥9
    

    Таким образом флаг u включает поддержку Юникода в регулярных выражениях.

    Конкретно, это означает, что:

    1. Символы из 4 байт воспринимаются как единое целое, а не как два символа по 2 байта.
    2. Работает поиск по Юникодным свойствам \p{…}.

    С помощью Юникодных свойств можно искать слова на нужных языках, специальные символы (кавычки, обозначения валюты) и так далее.

    Справочник JavaScript
    ×
    Справочник JavaScript