Регулярные выражения в "JavaScript". Шпаргалка по регулярным выражениям Ссылка на найденную группу

Регулярные выражения (RegExp ) - это очень эффективный способ работы со строками.

Составив регулярное выражение с помощью специального синтаксиса вы можете:

  • искать текст в строке
  • заменять подстроки в строке
  • извлекать информацию из строки

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

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

Регулярные выражения реализованные в UNIX, таких как grep, sed и популярных текстовых редакторах, начали набирать популярность и были добавлены в язык программирования Perl, а позже и в множество других языков.

JavaScript, наряду с Perl, это один из языков программирования в котором поддержка регулярных выражений встроена непосредственно в язык.

Сложно, по полезно

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

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

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

Это руководство нацелено на то чтобы самым простым способом дать вам некоторое представление о регулярных выражениях в JavaScript и предоставить информацию о том как читать и создавать регулярные выражения.

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

Как выглядят регулярные выражения

В JavaScript регулярные выражения это объект, который может быть определён двумя способами.

Первый способ заключается в создании нового объекта RegExp с помощью конструктора:

Const re1 = new RegExp("hey")

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

Const re1 = /hey/

Вы знаете что в JavaScript есть литералы объектов и литералы массивов ? В нём также есть литералы regexp .

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

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

Как они работают?

Регулярное выражение, которое мы определили выше как re1 , очень простое. Оно ищет строку hey без каки-либо ограничений: строка может содержать много текста, а слово hey находиться где-то в середине и регулярное выражение сработает. Строка может содержать только слово hey и регулярка опять сработает.

Это довольно просто.

Вы можете попробовать протестировать регулярное выражение с помощью метода RegExp.test(String) , который возвращает логическое (boolean) значение:

Re1.test("hey") // ✅ re1.test("blablabla hey blablabla") // ✅ re1.test("he") // ❌ re1.test("blablabla") // ❌

В примере выше мы просто проверили удовлетворяет ли "hey" шаблону регулярного выражения, который храниться в re1 .

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

Закрепление

/hey/

сработает независимо от того где находится hey внутри строки.

Если вы хотите найти строки, которые начинаются с hey , то используйте оператор ^ :

/^hey/.test("hey") // ✅ /^hey/.test("bla hey") // ❌

Если вы хотите найти строки, которые заканчиваются на hey , то используйте оператор $ :

/hey$/.test("hey") // ✅ /hey$/.test("bla hey") // ✅ /hey$/.test("hey you") // ❌

Объединяя два предыдущих оператора вы можете найти строку, которая полностью совпадает с hey:

/^hey$/.test("hey") // ✅

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

/^hey.*joe$/.test("hey joe") // ✅ /^hey.*joe$/.test("heyjoe") // ✅ /^hey.*joe$/.test("hey how are you joe") // ✅ /^hey.*joe$/.test("hey joe!") // ❌

Поиск элементов по диапазону

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

// // a, b, c, ... , x, y, z // // A, B, C, ... , X, Y, Z // // a, b, c // // 0, 1, 2, 3, ... , 8, 9

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

//.test("a") // ✅ //.test("1") // ❌ //.test("A") // ❌ //.test("d") // ❌ //.test("dc") // ✅

Диапазоны можно комбинировать:

// //.test("a") // ✅ //.test("1") // ✅ //.test("A") // ✅

Поиск многократных совпадений элемента диапазона

Вы можете проверить содержит ли строка только один символ из диапазона с помощью символа - :

/^$/ /^$/.test("A") // ✅ /^$/.test("Ab") // ❌

Инверсия шаблона

Символ ^ в начале шаблона привязывает его к началу строки.

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

/[^A-Za-z0-9]/.test("a") // ❌ /[^A-Za-z0-9]/.test("1") // ❌ /[^A-Za-z0-9]/.test("A") // ❌ /[^A-Za-z0-9]/.test("@") // ✅

Метасимволы

  • \d совпадает с любым числом, эквивалентно
  • \D совпадает с любым символом, который не является числом, эквивалентно [^0-9]
  • \w совпадает с любым буквенно-числовым символом, эквивалентно
  • \W совпадает с любым символом, который не является буквенно-числовым значением, эквивалентно [^A-Za-z0-9]
  • \s совпадает с любым пробельным символом: пробел, табуляция, символ новой строки и пробелы Unicode
  • \S совпадает с любым символом, который не является пробелом
  • \0 совпадает с null
  • \n совпадает с символом новой строки
  • \t совпадает с символом табуляции
  • \uXXXX совпадает с символом Unicode с кодом XXXX (требуется флаг u)
  • . совпадает с любым символовом, кроме символа новой строки (таким как \n) (если вы не используете флаг s , объясним позже)
  • [^] совпадает с любым символом, включая символ новой строки. Полезно при работе с многострочными строками

Выбор в регулярных выражениях

Если вы хотите выбрать одну или другую строку, используйте оператор | .

/hey|ho/.test("hey") // ✅ /hey|ho/.test("ho") // ✅

Квантификаторы

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

Вы можете использовать квантификатор ? , который сделает этот символ необязательным. В нашем случае цифра должна встречаться 0 или 1 раз:

но что если мы хотим чтобы регулярное выражение срабатывало на несколько цифр?

Вы можете сделать это 4 способами, используя + , * , {n} и {n,m} .

+

Совпадает с одним или более (>=1) элементами:

/^\d+$/ /^\d+$/.test("12") // ✅ /^\d+$/.test("14") // ✅ /^\d+$/.test("144343") // ✅ /^\d+$/.test("") // ❌ /^\d+$/.test("1a") // ❌

*

Совпадает с 0 или более (>=0) элементами:

/^\d+$/ /^\d*$/.test("12") // ✅ /^\d*$/.test("14") // ✅ /^\d*$/.test("144343") // ✅ /^\d*$/.test("") // ✅ /^\d*$/.test("1a") // ❌

{n}

Совпадает точно с n количеством элементов:

/^\d{3}$/ /^\d{3}$/.test("123") // ✅ /^\d{3}$/.test("12") // ❌ /^\d{3}$/.test("1234") // ❌ /^{3}$/.test("Abc") // ✅

{n,m}

Совпадает с диапазоном от n до m элементов:

/^\d{3,5}$/ /^\d{3,5}$/.test("123") // ✅ /^\d{3,5}$/.test("1234") // ✅ /^\d{3,5}$/.test("12345") // ✅ /^\d{3,5}$/.test("123456") // ❌

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

/^\d{3,}$/ /^\d{3,}$/.test("12") // ❌ /^\d{3,}$/.test("123") // ✅ /^\d{3,}$/.test("12345") // ✅ /^\d{3,}$/.test("123456789") // ✅

Опциональные элементы

Следующий за элементом знак? , сделает его необязательным:

/^\d{3}\w?$/ /^\d{3}\w?$/.test("123") // ✅ /^\d{3}\w?$/.test("123a") // ✅ /^\d{3}\w?$/.test("123ab") // ❌

Группы

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

Пример ниже ищет точное совпадение из 3 цифр за которым следует один или более буквенно-числовые символов:

/^(\d{3})(\w+)$/ /^(\d{3})(\w+)$/.test("123") // ❌ /^(\d{3})(\w+)$/.test("123s") // ✅ /^(\d{3})(\w+)$/.test("123something") // ✅ /^(\d{3})(\w+)$/.test("1234") // ✅

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

/^(\d{2})+$/ /^(\d{2})+$/.test("12") // ✅ /^(\d{2})+$/.test("123") // ❌ /^(\d{2})+$/.test("1234") // ✅

Захват групп

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

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

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

По умолчанию, группы итак захватываются. Теперь вместо использования RegExp.test(String) , который просто возвращает логическое значение, мы будем использовать один из следующих методов:

  • String.match(RegExp)
  • RegExp.exec(String)

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

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

"123s".match(/^(\d{3})(\w+)$/) //Array [ "123s", "123", "123s" ] /^(\d{3})(\w+)$/.exec("123s") //Array [ "123s", "123", "s" ] "hey".match(/(hey|ho)/) //Array [ "hey", "hey" ] /(hey|ho)/.exec("hey") //Array [ "hey", "hey" ] /(hey|ho)/.exec("ha!") //null

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

"123456789".match(/(\d)+/) //Array [ "123456789", "9" ]

Опциональные группы

Захват групп можно сделать опциональным с помощью (...)? . Если ничего не будет найдено, то в возвращаемый массив будет добавлен элемент undefined:

/^(\d{3})(\s)?(\w+)$/.exec("123 s") //Array [ "123 s", "123", " ", "s" ] /^(\d{3})(\s)?(\w+)$/.exec("123s") //Array [ "123s", "123", undefined, "s" ]

Ссылка на найденную группу

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

Именованный захват групп

Это новая возможность ES2018.

Группе можно назначить имя, а не просто слот в возвращаемом массиве:

Const re = /(?\d{4})-(?\d{2})-(?\d{2})/ const result = re.exec("2015-01-02") // result.groups.year === "2015"; // result.groups.month === "01"; // result.groups.day === "02";

Использование match и exec без групп

Существует разница при использовании match и exec без групп: в первом элементе массива будет находится не полностью найденная строка, а прямое совпадение:

/hey|ho/.exec("hey") // [ "hey" ] /(hey).(ho)/.exec("hey ho") // [ "hey ho", "hey", "ho" ]

Незахватываемые группы

Так как по умолчанию группы являются захватываемыми, нам нужен способ игнорировать некоторые группы в возвращаемом массиве. Это возможно с помощью незахватываемых групп , которые начинаются с (?:...) .

"123s".match(/^(\d{3})(?:\s)(\w+)$/) // null "123 s".match(/^(\d{3})(?:\s)(\w+)$/) // Array [ "123 s", "123", "s" ]

Флаги

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

  • g: ищет совпадения глобально
  • i: делает регулярное выражение не чувствительным к регистру
  • m: включает многострочный режим. В этом режиме ^ и $ совпадают с началом и концом всей строки. Без этого флага, с многострочными строками они совпадают с началом и концом каждой строки.
  • u: включает поддержку Unicode (добавлено в ES6/ES2015)
  • s: (новое в ES2018) сокращение от "single line", он позволяет. совпадать с символами новой строки

Флаги можно комбинировать, а также они добавляются в конец строки литерала:

/hey/ig.test("HEy") // ✅

или передаются вторым параметром в конструктор объекта RegExp:

New RegExp("hey", "ig").test("HEy") // ✅

Инспектирование регулярных выражений

Вы можете инспектировать свойства регулярных выражений:

  • source - строка шаблона
  • multiline - принимается значение true если установлен флаг m
  • global - принимается значение true если установлен флаг g
  • ignoreCase - принимается значение true если установлен флаг i
  • lastIndex
/^(\w{3})$/i.source //"^(\\d{3})(\\w+)$" /^(\w{3})$/i.multiline //false /^(\w{3})$/i.lastIndex //0 /^(\w{3})$/i.ignoreCase //true /^(\w{3})$/i.global //false

Экранирование

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

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

/^\\$/ /^\^$/ // /^\^$/.test("^") ✅ /^\$$/ // /^\$$/.test("$") ✅

Границы строк

\b и \B позволяют определить находится ли строка в начале или конце слова:

  • \b совпадает если набор символов находится в начале или конце слова
  • \B совпадает если набор символов не находится в начале или конце слова

"I saw a bear".match(/\bbear/) //Array ["bear"] "I saw a beard".match(/\bbear/) //Array ["bear"] "I saw a beard".match(/\bbear\b/) //null "cool_bear".match(/\bbear\b/) //null

Замена с помощью регулярных выражений

Мы уже видели как нужно проверять строки на совпадение с шаблоном.

Также мы видели как можно извлекать часть строк соотвествующие шаблону в массив.

Теперь давайте рассмотрим как заменять части строки на основе шаблона.

У объекта String в JavaScript есть метод replace() , который можно использовать без регулярных выражений для одной замены в строке:

"Hello world!".replace("world", "dog") //Hello dog! "My dog is a good dog!".replace("dog", "cat") //My cat is a good dog!

Этот метод также может принимать и регулярное выражение в качестве аргумента:

"Hello world!".replace(/world/, "dog") //Hello dog!

Использование флага g - это единственный способ заменить несколько вхождений в строке на ванильном JavaScript:

"My dog is a good dog!".replace(/dog/g, "cat") //My cat is a good cat!

Группы позволяют нам делать больше причудливых вещей, менять местами части строк:

"Hello, world!".replace(/(\w+), (\w+)!/, "$2: $1!!!") // "world: Hello!!!"

Вместо строки можно использовать функцию, чтобы делать ещё более интересные вещи. В неё будет передан ряд аргументов, таких как возвращают методы String.match(RegExp) или RegExp.exec(String) , где количество аргументов зависит от количества групп:

"Hello, world!".replace(/(\w+), (\w+)!/, (matchedString, first, second) => { console.log(first); console.log(second); return `${second.toUpperCase()}: ${first}!!!` }) //"WORLD: Hello!!!"

Жадность

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

Что это значит?

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

/\$(.+)\s?/

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

/\$(.+)\s?/.exec("This costs $100") //0

но что если у нас есть больше слов после числа, это отвлекает

/\$(.+)\s?/.exec("This costs $100 and it is less than $200") //100 and it is less than $200

Почему? Потому что регулярное выражение после знака $ совпадает с любым символом.+ и не останавливается пока не достигнет конца строки. Затем он останавливается, потому что \s? делает конечное пространство необязательным.

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

/\$(.+?)\s/.exec("This costs $100 and it is less than $200") //100

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

Опережение: соответствие строки в зависимости от того что за ней следует

Используйет?= для поиска совпадений в строке за которой следует определённая подстрока

/Roger(?=Waters)/ /Roger(?= Waters)/.test("Roger is my dog") //false /Roger(?= Waters)/.test("Roger is my dog and Roger Waters is a famous musician") //true

Выполняет обратную операцию и находит совпадений в строке за которыми не следует определённая подстрока:

/Roger(?!Waters)/ /Roger(?! Waters)/.test("Roger is my dog") //true /Roger(?! Waters)/.test("Roger is my dog and Roger Waters is a famous musician") //false

Ретроспектива: соответствие строки в зависимости от того что ей предшествует

Это новая возможность ES2018.

Опережение использует символ?= . Ретроспектива использует?<= :

/(?<=Roger) Waters/ /(?<=Roger) Waters/.test("Pink Waters is my dog") //false /(?<=Roger) Waters/.test("Roger is my dog and Roger Waters is a famous musician") //true

Инверсия ретроспективы использует?

/(?

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

Флаг u является обязательным при работе с Unicode строками, в частности когда может понадобится обрабатывать строки в астральных плоскостях, которые не включены в первые 1600 символов Unicode.

Например эмодзи, но и только они.

/^.$/.test("a") // ✅ /^.$/.test("?") // ❌ /^.$/u.test("?") // ✅

Поэтому, всегда используйте флаг u .

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

//.test("a") // ✅ //.test("1") // ✅ /[?-?]/u.test("?") // ✅ /[?-?]/u.test("?") // ❌

JavaScript проверяет внутренние коды представления, поэтому? < ? < ? на самом деле \u1F436 < \u1F43A < \u1F98A . Посмотрите полный список эмодзи чтобы увидеть коды и узнать их порядок.

Экранирование свойств Unicode

Как мы говорили выше, в шаблоне регулярного выражения вы можете использовать \d чтобы найти совпадение на любую цифру, \s чтобы найти совпадение на любой символ кроме пробела, \w чтобы найти совпадение на любой буквенно-числовой символ и т. д.

Экранирование свойств Unicode - это возможность ES2018, которая добавляет очень крутую функцию, расширяя эту концепцию на всех Unicode символы и добавляя \p{} и \P{} .

У любого Unicode символа есть набор свойств. Например Script определяет семейство языков, ASCII - это логическое значение равное true для ASCII символов и т.д. Вы можете положить это свойство в фигурные скобки и регулярное выражение будет проверять чтобы его значение было истинным:

/^\p{ASCII}+$/u.test("abc") // ✅ /^\p{ASCII}+$/u.test("ABC@") // ✅ /^\p{ASCII}+$/u.test("ABC?") // ❌

ASCII_Hex_Digit - это ещё одно логическое свойство, которое проверяет содержит ли строка тольк валидные шестнадцатеричные цифры:

/^\p{ASCII_Hex_Digit}+$/u.test("0123456789ABCDEF") //✅ /^\p{ASCII_Hex_Digit}+$/u.test("h")

Существует много других логических свойств, которые вы можете проверить просто добавив их имя в фигурные скобки, включая Uppercase , Lowercase , White_Space , Alphabetic , Emoji и другие:

/^\p{Lowercase}$/u.test("h") // ✅ /^\p{Uppercase}$/u.test("H") // ✅ /^\p{Emoji}+$/u.test("H") // ❌ /^\p{Emoji}+$/u.test("??") // ✅

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

/^\p{Script=Greek}+$/u.test("ελληνικά") // ✅ /^\p{Script=Latin}+$/u.test("hey") // ✅

Примеры

Извлечение числа из строки

Предположим, что есть строка содержащая только одно число, которое нужно извлечь. /\d+/ должен сделать это:

"Test 123123329".match(/\d+/) // Array [ "123123329" ]

Поиск E-mail адреса:

Простейший подход заключается в проверке безпробельных символов до и после знака @ , с помощью \S:

/(\S+)@(\S+)\.(\S+)/ /(\S+)@(\S+)\.(\S+)/.exec("[email protected]") //["[email protected]", "copesc", "gmail", "com"]

Однако, это упрощенный пример, так как под него попадает множество не валидных E-mail адресов.

Захват текста между двойными кавычками

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

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

Мы найдём то что нам нужно в result :

Const hello = "Hello "nice flower"" const result = /"([^"]*)"/.exec(hello) //Array [ "\"nice flower\"", "nice flower" ]

Получение содержимого из HTML тега

Например получить содержимое из тега span , допуская при этом любое количество аргументов у тега:

/]*>(.*?)<\/span>/ /]*>(.*?)<\/span>/.exec("test") // null /]*>(.*?)<\/span>/.exec("test") // ["test", "test"] /]*>(.*?)<\/span>/.exec("test") // ["test", "test"]

Регулярные выражения - это язык, который описывает шаблоны строк, основанные на метасимволах. Метасимвол – это символ в регулярном выражении, который описывает некоторый класс символов строки, указывает на положение подстроки, указывает количество повторений или группирует символы в подстроку. Например, метасимвол \d описывает цифры, а $ обозначает конец строки. В регулярном выражении могут присутствовать и обычные символы, которые описывают самих себя. Набор и значение метасимволов в регулярных выражениях описывает стандарт PCRE, большинство возможностей которого поддерживается в JS.

Область применения регулярных выражений

Регулярные выражения используются, как правило, для следующих задач:

  • Сопоставление . Целью этой задачи будет выяснить, соответствует ли определённый текст заданному регулярному выражению.
  • Поиск . С помощью регулярных выражений удобно находить соответствующие им подстроки и извлекать их из текста.
  • Замена . Регулярные выражения часто помогают не только найти, но и заменить в тексте подстроку, соответствующую регулярному выражению.

В конечном счёте при помощи регулярных выражений можно, например:

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

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

Главной особенностью регулярных выражений в JS является то, что для них существует отдельный вид литералов. Так же как строковые литералы обрамляются кавычками, литералы регулярных выражений обрамляются слешами (/). Таким образом JS-код может содержать выражения вида:

console.log(typeof /tcoder/); // object

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

var pattern = new RegExp("tcoder");

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

Символы в регулярных выражениях

Все алфавитно-цифровые символы в регулярных выражениях не являются метасимволами и описывают самих себя. Это значит, что регулярному выражению /tcoder/ будет соответствовать подстрока tcoder. В регулярных выражениях так же можно указывать не алфавитные символы, такие как: перевод строки (\n), табуляция (\t) и так далее. Все эти символы так же соответствуют сами себе. Поставленный перед алфавитным символом обратный слеш (\) сделает его метасимволом, если такой имеется. Например, алфавитный символ «d» станет метасимволом, описывающим цифры, если его предварить слешем (\d).

Классы символов

Одиночные символы в регулярных выражениях можно группировать в классы при помощи квадратных скобок. Созданному таким образом классу соответствует любой из включённых в него символов. Например, регулярному выражению // будут соответствовать буквы «t», «c», «o», «d», «e», «r».

В классах также можно задавать диапазон символов при помощи дефиса. Например, классу соответствует класс . Заметим, что некоторые метасимволы в регулярных выражениях уже описывают классы символов. Например, метасимвол \d эквивалентен классу . Заметим, что метасимволы, описывающие классы символов, также могут включаться в классы. Например, классу [\da-f] соответствуют цифры и буквы «a», «b», «d», «e», «f», то есть любой шестнадцатеричный символ.

Существует, также, возможность описать класс символов, указав символы, которые не должны в него входить. Делается это при помощи метасимвола ^. Например, классу [^\d] будет соответствовать любой символ кроме цифры.

Повторения

Теперь мы можем описать, скажем, десятичное число любой заданной длины, просто написав подряд столько метасимволов \d, сколько цифр в этом числе. Согласитесь, что такой подход не очень удобен. К тому же, мы не можем описать диапазон необходимого количества повторений. Например, мы не можем описать число из одной или двух цифр. К счастью, в регулярных выражениях существует возможность описывать диапазоны повторений при помощи метасимволов. Для этого после символа достаточно просто указать диапазон повторений в фигурных скобках. Например, регулярному выражению /tco{1, 3}der/ будут соответствовать строки «tcoder», «tcooder» и «tcooоder». Если опустить максимальное количество повторений, оставив запятую и минимальное количество повторений, то можно указать количество повторений больше заданного. Например, регулярному выражению /bo{2,}bs/ будут соответствовать строки «boobs», «booobs», «boooobs» и так далее с любым количеством букв «о» не меньше двух.

Если в фигурных скобках опустить и запятую, просто указав одно число, то оно будет обозначать точное количество повторений. Например, регулярному выражению /\d{5}/ соответствуют пятизначные числа.

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

Жадные повторения

Приведённый выше синтаксис описывает максимальное количество повторений, то есть из всех возможных количеств повторений, количество которых лежит в указанном диапазоне — выбирается максимальное. Такие повторения называют жадными. Это значит, что регулярному выражению /\d+/ в строке yeah!!111 будет соответствовать подcтрока «111», а не «11» или «1», хотя метасимвол «+» описывает одно и более повторений.

Если вы хотите реализовать нежадное повторение, то есть выбирать минимальное возможное количество повторений из указанного диапазона, то просто поставьте символ «?» после диапазона повторений. Например, регулярному выражению /\d+?/ в строке «yeah!!111» будет соответствовать подстрока «1», а регулярному выражению /\d{2,}/ в той же строке будет соответствовать подстрока «11».

Стоит обратить внимание на важную особенность нежадного повторения. Рассмотрим регулярное выражение /bo{2,}?bs/ . В строке «i like big boooobs» ему будет соответствовать, как и при жадном повторении, подстрока boooobs, а не boobs, как можно было подумать. Дело в том, что регулярному выражению при одном сопоставлении не может соответствовать несколько подстрок, расположенных в разных местах строки. То есть, нашему регулярному выражению не могут соответствовать подстроки «boo» и «bs», склеенные в одну строку.

Альтернативы

В регулярных выражениях так же можно использовать альтернативы — описывать множество строк, которое соответствует либо одной, либо другой части регулярного выражения. Такие части и называются альтернативами и разделяются при помощи вертикальной черты. Например, регулярному выражению /two|twice|\2/ может соответствовать либо подстрока «two», либо подстрока «twice», либо подстрока «2». Цепочка альтернатив обрабатывается слева на право до первого совпадения и ей может соответствовать только подстрока, которую описывает только одна альтернатива. Например, регулярному выражению /java|script/ в строке «I like javascript» будет соответствовать только подстрока «java».

Группировки

Чтобы рассматривать несколько символов как единое целое при использовании диапазонов повторений, классов символов и всего прочего, достаточно просто взять их в круглые скобки. Например, регулярному выражению /true(coder)?/ будут соответствовать строки «truecoder» и «true».

Ссылки

Кроме того, что круглые скобки объединяют символы в регулярном выражении в единое целое, на соответствующею им подстроку можно ссылаться, просто указав после слеша номер левой скобки из пары обрамляющих его скобок. Скобки нумеруются с лева на право начиная с единицы. Например, в регулярном выражении /(one(two)(three))(four)/ \1 ссылается на one, \2 на «two», \3 на «three», \4 на «four». В качестве примера использования таких ссылок приведём регулярное выражение /(\d)\1/ , которому соответствуют двухзначные числа с одинаковыми цифрами. Важным ограничением использования обратных ссылок является невозможность их использования в классах, то есть, например, описать двухзначное число с различными цифрами регулярным выражением /(\d)[^\1]/ нельзя.

Незапоминающие скобки

Часто бывает необходимо просто сгруппировать символы, но нет необходимости создавать ссылку. В этом случае можно сразу после левой группирующей скобки можно написать?:. Например, в регулярном выражении /(one)(?:two)(three)/ \2 будет указывать на «three».

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

Указание позиции

В регулярных выражениях так же существуют метасимволы, которые указывают на некоторую позицию в строке. Чаще всех остальных используются символы ^, $ указывающие на начало и конец строки. Например, регулярному выражению /\..+$/ будут соответствовать расширения в названиях файлов, а регулярному выражению /^\d/ первая цифра в строке, если она есть.

Позитивная и негативная опережающие проверки

При помощи регулярных выражений так же можно описать подстроку, за которой следует или не следует подстрока, описанная другим шаблоном. Например, нам необходимо найти слово java только если за ним следует «script». Эту задачу можно решить при помощи регулярного выражения /java(?=script)/ . Если же нам нужно описать подстроку «java» за которой не следует script можно воспользоваться регулярным выражением /java(?!script)/ .

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

Символ Значение
a|b Соответствует либо а, либо и.
(…) Группирующие скобки. Так же на подстроку, соотвествующую шаблону в скобках можно ссылаться.
(?:…) Только группировка, без возможности ссылаться.
\n Ссылка на подстроку, соответствующею n-ому шаблону.
^ Начало входных данных или начало строки.
$ Конец входных данных или конец строки.
a(?=b) Соответствует подстроке, которую описывает шаблон a, только если за ней следует подстрока, описанная шаблоном b.
a(?!b) Соответствует подстроке, которую описывает шаблон a, только если за ней не следует подстрока, описанная шаблоном b.

Флаги

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

В JavaScript существуют всего три флага регулярных выражений:

i – при указании этого флага регистр не учитывается, то есть, например, регулярному выражению \javascript\i будут соответствовать строки «javascript», «JavaScript», «JAVASCRIPT», «jAvAScript» и т.д.

m – этот флаг включает многострочный поиск. Это значит, что если в тексте есть символы перевода строк и этот флаг поставлен, то символы ^ и $ кроме начала и конца всего текста будут соответствовать так же ещё началу и концу каждой строки в тексте. Например, регулярному выражению /line$/m соответствует подстрока «line», как в строке «first line», так и в строке «one\nsecond line\ntwo».

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

Флаги можно комбинировать между собой в произвольном порядке, то есть \tcoder\mig , \tcоder\gim , \tocder\gmi и т.д., это одно и тоже. Порядок флагов так же не имеет значения, если их передавать в строке в качестве второго аргумента конструктору объекта RegExp , то есть new RegExp(«tcoder», «im») и new RegExp(«tcoder», «im») так же одно и тоже.

З.Ы.

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

JavaScript regexp – это тип объекта, который используется для сопоставления последовательности символов в строках.

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

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

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

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

Метод RegExp.prototype.test()

Помните, я говорил, что регулярные выражения являются объектами? Это означает, что у них есть ряд методов. Самый простой метод – это JavaScript regexp test , который возвращает логическое значение:

True (истина ): строка содержит шаблон регулярного выражения.

False (ложь ): совпадения не найдено.

console.log(/cat/.test(“the cat says meow”)); // верно console.log(/cat/.test(“the dog says bark”)); // неверно

Памятка по основам регулярных выражений

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

Символы

  • . – (точка ) соответствует любому одиночному символу за исключением переноса строки;
  • *  –  соответствует предыдущему выражению, которое повторяется 0 или более раз;
  • +  –  соответствует предыдущему выражению, которое повторяется 1 или более раз;
  • ? –  предыдущее выражение является необязательным (соответствует 0 или 1 раз );
  • ^ – соответствует началу строки;
  • $ – соответствует концу строки.

Группы символов

  • d –  соответствует любому одиночному цифровому символу.
  • w –  соответствует любому символу (цифре, букве или знаку подчёркивания).
  • [XYZ ]   –  набор символов. Соответствует любому одиночному символу из набора, заданного в скобках. Также можно задавать и диапазоны символов, например, .
  • [XYZ ]+   –  соответствует символу из набора, повторяемого один или более раз.
  • [^A —Z ]   –  внутри набора символов «^ » используется как знак отрицания. В данном примере шаблону соответствует всё, что не является буквами в верхнем регистре.

Флаги :

В JavaScript regexp существует пять необязательных флагов. Они могут использоваться отдельно или вместе, и размещаются после закрывающего слеша. Например: /[A —Z ]/g . Здесь я приведу только два флага.

g –  глобальный поиск.

i   –  поиск, нечувствительный к регистру.

Дополнительные конструкции

(x )   –   захватывающие скобки. Это выражение соответствует x и запоминает это соответствие, поэтому им можно воспользоваться позже.

(?:x )   –  незахватывающие скобки. Выражение соответствует x , но не запоминает это соответствие.

Соответствует x , только если за ним следует y .

Протестируем изученный материал

Сначала протестируем все выше сказанное. Допустим, что мы хотим проверить строку на наличие любых цифр. Для этого можно использовать конструкцию «d ».

console.log(/d/.test("12-34")); // верно

Приведенный выше код возвращает значение true , если в строке есть хотя бы одна цифра. Что делать, если нужно проверить строку на соответствие формату? Можно использовать несколько символов «d », чтобы определить формат:

console.log(/dd-dd/.test("12-34")); //верно console.log(/dd-dd/.test("1234")); //неверно

Если неважно, как в JavaScript regexp online идут цифры до и после знака «— », можно использовать символ «+ », чтобы показать, что шаблон «d » встречается один или несколько раз:

console.log(/d+-d+/.test("12-34")); // верно console.log(/d+-d+/.test("1-234")); // верно console.log(/d+-d+/.test("-34")); // неверно

Для простоты можно использовать скобки, чтобы сгруппировать выражения. Допустим, у нас есть мяуканье кошки, и мы хотим проверить соответствие шаблону «meow » (мяу ):

console.log(/me+(ow)+w/.test("meeeeowowoww")); // верно

Теперь давайте разберемся.

m => соответствие одной букве ‘m ‘;

e + => соответствие букве «e» один или несколько раз;

(ow) + => соответствие буквам «ow» один или несколько раз;

w => соответствие букве ‘w ’;

‘m’ + ‘eeee’ + ‘owowow’ + ‘w’ .

Когда операторы типа «+ » используются сразу после скобок, они влияют на все содержимое скобок.

Оператор «? ». Он указывает, что предыдущий символ является необязательным. Как вы увидите ниже, оба тестовых примера возвращают значение true , потому что символы «s » помечены как необязательные.

console.log(/cats? says?/i.test("the Cat says meow")); //верно console.log(/cats? says?/i.test("the Cats say meow")); //верно

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

var slashSearch = ///; var questionSearch = /?/;

  • d – это то же самое, что и : каждая конструкция соответствует цифровому символу.
  • w – это то же самое, что [A —Za —z 0-9_] : оба выражения соответствуют любому одиночному алфавитно-цифровому символу или подчеркиванию.

Пример: добавляем пробелы в строки, написанные в «верблюжьем» стиле

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

removeCc("camelCase") // => должен вернуть "camel Case"

Существует простое решение с использованием регулярного выражения. Во-первых, нам нужно найти все заглавные буквы. Это можно сделать с помощью поиска набора символов и глобального модификатора.

Это соответствует символу «C » в «camelCase »

Теперь, как добавить пробел перед «C »?

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

Получить доступ к захваченному значению позднее можно так:

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

Если вам нужно использовать скобки, но не нужно фиксировать это значение, можно использовать незахватывающие скобки: (?: x ). В этом случае находится соответствие x , но оно не запоминается.

Вернемся к текущей задаче. Как мы реализуем захватывающие скобки? С помощью метода JavaScript regexp replace ! В качестве второго аргумента мы передаем «$1 ». Здесь важно использовать кавычки.

function removeCc(str){ return str.replace(/()/g, "$1"); }

Снова посмотрим на код. Мы захватываем прописную букву, а затем заменяем ее той же самой буквой. Внутри кавычек вставим пробел, за которым следует переменная $1 . В итоге получаем пробел после каждой заглавной буквы.

function removeCc(str){ return str.replace(/()/g, " $1"); } removeCc("camelCase") // "camel Case" removeCc("helloWorldItIsMe") // "hello World It Is Me"

Пример: удаляем заглавные буквы

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

Мы снова будем использовать метод replace , но как в этот раз сделать строчной символ?

function lowerCase(str){ return str.replace(//g, ???); }

Подсказка : в методе replace () в качестве второго параметра можно указать функцию.

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

function lowerCase(str){ return str.replace(//g, (u) => u.toLowerCase()); } lowerCase("camel Case") // "camel case" lowerCase("hello World It Is Me") // "hello world it is me"

В JavaScript регулярные выражения представлены объектами RegExp . Объекты RegExp могут быть созданы посредством конструктора RegExp(), но чаще они создаются с помощью специального синтаксиса литералов. Так же как строковые литералы задаются в виде символов, заключенных в кавычки, литералы регулярных выражений задаются в виде символов, заключенных в пару символов слэша / .

/pattern/флаги new RegExp("pattern"[, опции поиска])

pattern - регулярное выражение для поиска (о замене - позже), а флаги - строка из любой комбинации символов g(глобальный поиск), i(регистр неважен) и m(многострочный поиск). Первый способ используется часто, второй - иногда. Например, два таких вызова эквивалентны.

Опции поиска

При создании регулярного выражения мы можем указать дополнительных опции поиска

Символы в регулярных выражениях JavaScript

Символ Соответствие
Алфавитно-цифровые символы Соответствуют сами себе
\0 Символ NUL (\u0000)
\t Табуляция (\u0009)
\n Перевод строки (\u000A)
\v Вертикальная табуляция (\u000B)
\f Перевод страницы (\u000C)
\r Возврат каретки (\u000D)
\xnn Символ из набора Latin, задаваемый шестнадцатеричным числом nn; например, \x0A - это то же самое, что \n
\uxxxx Unicode-символ, заданный шестнадцатеричным числом xxxx; например, \u0009 - это то же самое, что \t
\cX Управляющий символ "X", например, последовательность \cJ эквивалентна символу перевода строки \n
\ Для обычных символов - делает их специальными. Например, выражение /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 повторений элемента.
Набор символов. Находит любой из перечисленных символов. Вы можете указать промежуток, используя тире. Например, - то же самое, что . Найдет "b" в "brisket", а также "a" и "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 находит цифру из любого алфавита (у нас же юникод). Испльзуйте , чтобы найти только обычные цифры. Например, /\d/ или // найдет "2" в "B2 is the suite number."
\D Найдет нецифровой символ (все алфавиты). [^0-9] - эквивалент для обычных цифр. Например, /\D/ или /[^0-9]/ найдет "B" в "B2 is the suite number."
\s Найдет любой пробельный символ, включая пробел, табуляцию, переводы строки и другие юникодные пробельные символы. Например, /\s\w*/ найдет " bar" в "foo bar."
\S Найдет любой символ, кроме пробельного. Например, /\S\w*/ найдет "foo" в "foo bar."
\v Символ вертикальной табуляции.
\w Найдет любой словесный (латинский алфавит) символ, включая буквы, цифры и знак подчеркивания. Эквивалентно . Например, /\w/ найдет "a" в "apple," "5" в "$5.28," и "3" в "3D."
\W Найдет любой не-(лат.)словесный символ. Эквивалентно [^A-Za-z0-9_] . Например, /\W/ и /[^$A-Za-z0-9_]/ одинаково найдут "%" в "50%."

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

Работа с регулярными выражениями в Javascript реализована методами класса String

exec(regexp) - находит все совпадения (вхождения в шаблон "регулярки") в строке. Возвращает массив (при совпадении) и обновляет свойство regexp-а, или null - если ничего не найдено,. С модификатором g - при каждом вызове этой функции, она будет возвращать следующее совпадение после предыдущего найденного - это реализовано с помощью ведения индекса смещения последнего поиска.

match(regexp) - найти часть строки по шаблону. Если указан модификатор g, то функция match() возвращает массив всех совпадений или null (а не пустой массив). Без модификатора g эта функция работает как exec();

test(regexp) - функция проверяет строку на соответствие шаблону. Возвращает true - если есть совпадение, и false - если совпадения нет.

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

replace(regexp, mix) - метод возвращает строку изменную в соответствии с шаблоном (регуляррным выражением). Первый параметр regexp также может содержать строку, а не регулярное выражение. Без модификатора g - метод в строке заменяет только первое вхождение; с модификатором g - происходит глобальная замена, т.е. меняются все вхождения в данной строке. mix - шаблон замены, может принитать значения строки, шаблона замены, функции (имя функции).

Спецсимволы в строке замены

Замена через функцию

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

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

Синтаксис:

//Первый вариант создания регулярного выражения var regexp=new RegExp(шаблон ,модификаторы ); //Второй вариант создания регулярного выражения var regexp=/шаблон /модификаторы ;

шаблон позволяет задать шаблон символов для поиска.

модификаторы позволяют настроить поведение поиска:

  • i - поиск без учета регистра букв;
  • g - глобальный поиск (будут найдены все совпадения в документе, а не только первое);
  • m - многострочный поиск.

Поиск слов и выражений

Самым простым применением регулярных выражений является поиск слов и выражений в различных текстах.

Приведем пример использования поиска с применением модификаторов:

//Зададим регулярное выражение rv1 rv1=/Россия/; //Зададим регулярное выражение rv2 rv2=/Россия/g; //Зададим регулярное выражение rv3 rv3=/Россия/ig; //Жирным шрифтом выделено, где в тексте будут найдены совпадения при использовании //выражения rv1: Россия является крупнейшим государством мира. Россия граничит с 18 странами. РОССИЯ является государством-продолжателем СССР. //Жирным шрифтом выделено, где в тексте будут найдены совпадения при использовании //выражения rv2: Россия является крупнейшим государством мира. Россия граничит с 18 странами. РОССИЯ является государством-продолжателем СССР."; //Жирным шрифтом выделено, где в тексте будут найдены совпадения при использовании //выражения rv3: Россия является крупнейшим государством мира. Россия граничит с 18 странами. РОССИЯ является государством - продолжателем СССР.";

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

Помимо обычных символов в шаблонах регулярных выражений могут использоваться специальные символы (метасимволы). Специальные символы с описаниями приведены в таблице ниже:

Специальный символ Описание
. Совпадает с любым символом, кроме символа конца строки.
\w Совпадает с любым буквенным символом.
\W Совпадает с любым не буквенным символом.
\d Совпадает с символами, которые являются цифрами.
\D Совпадает с символами, которые не являются цифрами.
\s Совпадает с пробельными символами.
\S Совпадает с не пробельными символами.
\b Совпадения будут искаться только на границах слов (в начале или конце).
\B Совпадения будут искаться только не на границах слов.
\n Совпадает с символом перевода строки.

/* Выражение reg1 найдет все слова начинающиеся на две произвольные буквы и заканчивающиеся на "вет". Так как слова в предложении разделяются пробелом, то в начале и в конце добавим спецсимвол \s) */ reg1=/\s..вет\s/g; txt=" привет завет вельвет клозет "; document.write(txt.match(reg1) + "
"); /* Выражение reg2 найдет все слова начинающиеся на три произвольные буквы и заканчивающиеся на "вет" */ reg2=/\s...вет\s/g; document.write(txt.match(reg2) + "
"); txt1=" при2вет привет при1вет "; /* Выражение reg3 найдет все слова, которые начинаются на "при" в которых потом следует 1 цифра и заканчиваются на "вет" */ var reg3=/при\dвет/g; document.write(txt1.match(reg3) + "
"); // Выражение reg4 найдет все цифры в тексте var reg4=/\d/g; txt2="5 лет учебы, 3 года плавания, 9 лет стрельбы." document.write(txt2.match(reg4) + "
");

Быстрый просмотр

Символы в квадратных скобках

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

Символ ^ перед группой символов в квадратных скобках [^квг] говорит о том, что нужно произвести поиск всех символов алфавита кроме заданных.

Используя тире (-) между символами в квадратных скобках [а-з] Вы можете задать диапазон символов, поиск которых нужно произвести.

С помощью квадратных скобок Вы можете также искать числа.

//Зададим регулярное выражение reg1 reg1=/\sко[тдм]\s/g; //Зададим строку текста txt1 txt1=" кот коса код комод ком ковер "; //Произведем с помощью регулярного выражения reg1 поиск по строке txt1 document.write(txt1.match(reg1) + "
"); reg2=/\sсло[^тг]/g; txt2=" слот слон слог "; document.write(txt2.match(reg2) + "
"); reg3=//g; txt3="5 лет учебы, 3 года плавания, 9 лет стрельбы"; document.write(txt3.match(reg3));

Быстрый просмотр

Квантификаторы

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

Синтаксис:

//Предшествующий символ должен встречаться x - раз {x} //Предшествующий символ должен встречаться от x до у раз включительно {x,y} //Предшествующий символ должен встречаться не менее x раз {x,} //Указывает, что предшествующий символ должен встречаться 0 или более раз * //Указывает что предшествующий символ должен встречаться 1 или более раз + //Указывает что предшествующий символ должен встречаться 0 или 1 раз ?


//Зададим регулярное выражение rv1 rv1=/ко{5}шка/g //Зададим регулярное выражение rv2 rv2=/ко{3,}шка/g //Зададим регулярное выражение rv3 rv3=/ко+шка/g //Зададим регулярное выражение rv4 rv4=/ко?шка/g //Зададим регулярное выражение rv5 rv5=/ко*шка/g //Жирным шрифтом показано, где в тексте будут найдены совпадения при использовании //выражения rv1: кшка кошка коошка кооошка коооошка кооооошка коооооошка кооооооошка //Жирным шрифтом показано, где в тексте будут найдены совпадения при использовании //выражения rv2: кшка кошка коошка кооошка коооошка кооооошка коооооошка кооооооошка //Жирным шрифтом показано, где в тексте будут найдены совпадения при использовании //выражения rv3: кшка кошка коошка кооошка коооошка кооооошка коооооошка кооооооошка //Жирным шрифтом показано, где в тексте будут найдены совпадения при использовании //выражения rv4: кшка кошка коошка кооошка коооошка кооооошка коооооошка кооооооошка //Жирным шрифтом показано, где в тексте будут найдены совпадения при использовании //выражения rv5: кшка кошка коошка кооошка коооошка кооооошка коооооошка кооооооошка

Обратите внимание: если Вы хотите использовать какой-либо специальный символ (такой как. * + ? или {}) как обычный Вы должны поставить перед ним \.

Использование круглых скобок

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

К примеру регулярное выражение /(Дмитрий)\sВасильев/ найдет строку "Дмитрий Васильев" и запомнит подстроку "Дмитрий".

В примере ниже мы используем метод replace(), чтобы изменить порядок слов в тексте. Для обращения к сохраненным совпадениям мы используем $1 и $2.

Var regexp = /(Дмитрий)\s(Васильев)/; var text = "Дмитрий Васильев"; var newtext = text.replace(regexp, "$2 $1"); document.write(newtext);

Быстрый просмотр

Круглые скобки могут использоваться для группировки символов перед квантификаторами.