Регулярні вирази

Найти все / Заменить все

Эти две задачи решаются в javascript принципиально по-разному.

Начнем с «простого».

Для замены всех вхождений используется метод String#replace.
Он интересен тем, что допускает первый аргумент — регэксп или строку.

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

Попробуйте:

alert("2 ++ 1".replace("+", "*"))

Каков результат? Как, заменился только один плюс, а не два? Да, вот так.

В режиме регулярного выражения плюс придется заэкранировать, но зато заменит все вхождения (при указании флага ):

alert("2 ++ 1".replace(/\+/g, "*"))

Вот такая особенность работы со строкой.

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

Следующий пример произведет операции вычитания:

var str = "count 36 - 26, 18 - 9"
str = str.replace(/(\d+) - (\d+)/g, function(a,b,c) { return b-c })
alert(str)

В javascript нет одного универсального метода для поиска всех совпадений.
Для поиска без запоминания скобочных групп — можно использовать String#match:

var str = "count 36-26, 18-9"
var re =  /(\d+)-(\d+)/g
result = str.match(re)
for(var i=0; i<result.length; i++) alert(result)

Как видите, оно исправно ищет все совпадения (флаг у регулярного выражения обязателен), но при этом не запоминает скобочные группы. Эдакий «облегченный вариант».

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

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

var str = "count 36-26, 18-9"
var re =  /(\d+)-(\d+)/g
var res
while ( (res = re.exec(str)) != null) {
  alert("Найдено " + res + ":  ("+ res+") и ("+res+")")
  alert("Дальше ищу с позиции "+re.lastIndex)
}

Проверка нужна т.к. значение является хорошим и означает, что вхождение найдено в самом начале строки (поиск успешен). Поэтому необходимо сравнивать именно с .

Жадность

Это не совсем особенность, скорее фича, но все же достойная отдельного абзаца.

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

Например, мы хотим заменить все открывающие тэги

На что и почему — не так важно

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

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

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

Последний символ точка-звездочка не захватывает, т.к. иначе не будет совпадения.

Как вариант решения используют квадратные скобки: :

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

Это работает. Но самым удобным вариантом является переключение точки-звездочки в нежадный режим. Это осуществляется простым добавлением знака «» после звездочки.

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

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

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

В javascript это сделать нельзя.. Вот такая особенность. А вопросительный знак после звездочки рулит — честное слово.

Методы RegExp

Ниже приведен список методов, связанных с RegExp, а также их описание.

Свойство Описание
exec() Выполняет поиск соответствия в своем строковом параметре.
test() Тесты для соответствия в параметре строки.
toSource() Возвращает литерал объекта, представляющий указанный объект; вы можете использовать это значение для создания нового объекта.
toString() Возвращает строку, представляющую указанный объект.

Новые статьи

  • JS База данных — фильтрация записей. Часть 2 — 15/12/2019 05:21
  • JavaScript — Совместимость с браузерами — 08/09/2018 15:52
  • JavaScript — Карта изображений — 08/09/2018 15:52
  • JavaScript — отладка — 08/09/2018 15:51
  • JavaScript — Мультимедиа — 08/09/2018 15:51
  • JavaScript — анимация — 08/09/2018 15:50
  • JavaScript — подтверждение формы — 08/09/2018 15:50
  • JavaScript — Обработка ошибок и исключений — 08/09/2018 15:49
  • JavaScript — Объектная модель документа или DOM — 08/09/2018 15:49

Предыдущие статьи

  • JavaScript — объект Math — 08/09/2018 15:48
  • JavaScript — объект Date — 08/09/2018 15:48
  • JavaScript — объект Array — 08/09/2018 15:47
  • JavaScript — объект Strings — 08/09/2018 15:47
  • JavaScript — логические объекты — 08/09/2018 15:46
  • JavaScript — Числовые объекты — 08/09/2018 15:46
  • JavaScript — Обзор объектов — 08/09/2018 15:45
  • JavaScript — Печать страницы — 08/09/2018 15:45
  • JavaScript — Void — 08/09/2018 15:45
  • JavaScript — диалоговые окна — 08/09/2018 15:44
  • JavaScript — Redirect — 08/09/2018 15:44
  • JavaScript и Cookies — 08/09/2018 15:43
  • JavaScript — События — 08/09/2018 15:43
  • JavaScript — функции — 08/09/2018 15:42
  • JavaScript — управление циклом — 08/09/2018 15:41
  • JavaScript — цикл for … in — 08/09/2018 15:41
  • JavaScript — For цикл — 08/09/2018 15:40
  • JavaScript — циклы — 08/09/2018 15:40
  • JavaScript — switch-case — 08/09/2018 15:39
  • JavaScript — if … else — 08/09/2018 15:39

Флаги регулярных выражений

Флаг Описание
g Позволяет найти все совпадения, а не останавливаться после первого совпадения (global match flag).
i Позволяет выполнить сопоставление без учета регистра (ignore case flag).
m Сопоставление производится по нескольким строкам. Обработка начальных и конечных символов (^ и $) производится по нескольким строкам, то есть сопоставление происходит с началом или концом каждой строки (разделители \n или \r), а не только с началом, или концом всей строки (multiline flag).
u Шаблон будет расценен как последовательность кодовых точек Юникода (unicode flag).
y Сопоставление происходит по индексу на который указывает свойство lastIndex этого регулярного выражения, при этом сопоставление не производиться по более позднему, или раннему индексу (sticky flag).

Правила написания шаблонов в JavaScript

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

Итак, flag – это инструмент для установки глобального или регистронезависимого поиска. В JS можно использовать четыре вида флага. При этом вы можете их прописывать как по отдельности, так и комбинировать в разном порядке и количестве. Хочу заметить, что от смены порядка результат выполнение не изменится.

Флаг Предназначение
m Определяет многострочный поиск, т.е. образец сравнивается со всеми буквами, цифрами или другими знаками, которые разделены между собой известными пробельными символами.
i Поиск подстрок осуществляется без учета регистра.
y Выполнение проверки переменных начинается от символа, находящегося на позиции свойства под названием lastIndex.
g Задает глобальный поиск, после выполнения которого будут выведены все возможные совпадения.

Ну а теперь давайте рассмотрим первый простой пример для понимания происходящего. С помощью переменной regExp я проверяю, есть ли вхождение в text слова «вариант». При этом я хочу, чтобы вывелись все случаи вхождения без учета регистра.

1
2
3
4
5
6
<script>
var regExp = /вариант/gi;
var text = "Вариант 1. напишите стих, состоящий из четырех строк. Вариант 2. Допишите стих из варианта 1.";
var myArray = text.match(regExp );
alert(myArray);
</script>

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

Для поиска символов определенного вида в регулярных выражениях есть «классы символов». Например ищет одну цифру. Есть и другие классы.

Основные классы

  • – цифры.
  • – не-цифры.
  • – пробельные символы, переводы строки.
  • – всё, кроме \s.
  • – латиница, цифры, подчёркивание ‘_’.
  • – всё, кроме \w.
  • – символ табуляции
  • – символ перевода строки
  •  – точка обозначает любой символ, кроме перевода строки.

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

Наборы символов

  • – произвольный символ от a до z
  • произвольный символ от B до G в верхнем регистре
  • – то же самое, что и \d, любая цифра от 0 до 9
  •  – любая цифра или буква, можно комбинировать диапазоны
  •  – диапазон «кроме», ищет любые символы, кроме цифр

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

Не экранируем в квадратных скобках

  • Точка .
  • Плюс .
  • Круглые скобки .
  • Дефис , если он находится в начале или конце квадратных скобок, то есть не выделяет диапазон.
  • Символ каретки , если не находится в начале квадратных скобок.
  • А также открывающая квадратная скобка .

Квантификаторы +, *, ? и {n}

  • Количество {n} — 5 цифр — одна или больше цифр — от одной до 5 цифр
  • Один или более +, аналог {1,} — одна или более цифр — одна или более букв от a до z
  • Ноль или один ?, аналог {0,1} — найдет color и colour
  • Означает «ноль или более» *, аналог {0,} — найдет «1» и «100» в строке «1 100», символ может повторяться много раз или вообще отсутствовать.

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

Вы можете заключить одну или несколько частей шаблона в скобки — это и будет называться скобочной группой. Основной профит — при использовании методов match, exec, replace — можно вытащить значения в скобках в отдельный элемент массива. И еще, если поставить квантификатор после скобки, то он применится ко всей скобке, а не к одному символу. Еще вы можете использовать вложенные скобки, то есть разбивать большой шаблон на несколько маленьких.

Пример использования вы можете посмотреть выше — в нестандартном применении метода replace().

Простым языком, это «ИЛИ».

— аналог \d  -любая цифра — найдет «imacros» или «js»

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

Знак каретки ‘^’ и доллара ‘$’ имеют в регулярном выражении особый смысл. Их называют «якорями» (anchor – англ.).
Каретка совпадает в начале текста, а доллар – в конце. Знак доллара $ используют, чтобы указать, что паттерн должен заканчиваться в конце текста, знак каретки ^ — что паттерн должен начинаться с первого символа строки.

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

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

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

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

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

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

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

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

Точка – это любой символ

Точка – это специальный символьный класс, который соответствует «любому символу, кроме новой строки».

Для примера:

Или в середине регулярного выражения:

Обратите внимание, что точка означает «любой символ», но не «отсутствие символа». Там должен быть какой-либо символ, чтобы соответствовать условию поиска:. Обычно точка не соответствует символу новой строки

Обычно точка не соответствует символу новой строки .

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

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

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

Внимание, пробелы!

Обычно мы уделяем мало внимания пробелам. Для нас строки и практически идентичны.

Но если регулярное выражение не учитывает пробелы, оно может не сработать.

Давайте попробуем найти цифры, разделённые дефисом:

Исправим это, добавив пробелы в регулярное выражение :

Пробел – это символ. Такой же важный, как любой другой.

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

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

Примеры

Применение test()

Метод test() – регулярное выражение объекта RegExp. Он производит поиск строки шаблона, и в зависимости от полученного результата возвращает значение true или false. Следующий JS регулярного выражения пример показывает, как происходит поиск в строке символа “e”:

var patt = /e/;
patt.test("Лучшие в мире вещи – бесплатны!");

Так как здесь в строке имеется “e”, результатом данного кода будет значение true.

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

/e/.test("Лучшие в мире вещи – бесплатны!");

Применение exec()

Он производит поиск в строке по заданному правилу поиска, и возвращает найденный текст. Если совпадений найдено не было, то результатом будет null.

Посмотрим на метод в действии, на примере того же символа “e”:

/e/.exec("Лучшие в мире вещи – бесплатны!");

Так как в строке имеется “e”, результатом данного кода будет .e.

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

В Javascript эти выражения также можно использовать с двумя методами объекта String: search() и replace(). Они нужны для выполнения поиска и замены в тексте.

  • Метод search() — использует выражение для поиска соответствия, и возвращает информацию о расположении соответствия;
  • Метод replace() — возвращает модифицированную строку с замененным шаблоном.

Примеры

Применение регулярного выражения JS для осуществления чувствительного к регистру поиска фразы “w3schools” в строке:

var str = "Visit W3Schools";
var n = str.search(/w3schools/i);

Результатом в n будет 6.

Метод search также принимает строку в качестве аргумента. Аргумент string будет преобразован в регулярное выражение:

Применение string для поиска фразы “W3schools” в строке:

var str = "Visit W3Schools!";
var n = str.search("W3Schools");

Применение чувствительного к регистру регулярного выражения JS для замены «Microsoft» на «W3Schools» в строке:

var str = "Visit Microsoft!";
var res = str.replace(/microsoft/i, "W3Schools");

В результате мы получим: «Visit W3Schools!«.

Метод replace() также принимает строку для поиска:

var str = “Visit Microsoft!”;
var res = str.replace(“Microsoft”, “W3Schools”);

Данная публикация является переводом статьи «Using regular expression in Javascript» , подготовленная редакцией проекта.

Найти все / Заменить все

Эти две задачи решаются в javascript принципиально по-разному.

Начнём с «простого».

Для замены всех вхождений используется метод String#replace.
Он интересен тем, что допускает первый аргумент – регэксп или строку.

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

Попробуйте:

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

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

В режиме регулярного выражения плюс придётся экранировать, но зато заменит все вхождения (при указании флага ):

Вот такая особенность работы со строкой.

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

Следующий пример произведёт операции вычитания:

В javascript нет одного универсального метода для поиска всех совпадений.
Для поиска без запоминания скобочных групп – можно использовать String#match:

Как видите, оно исправно ищет все совпадения (флаг у регулярного выражения обязателен), но при этом не запоминает скобочные группы. Эдакий «облегчённый вариант».

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

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

Проверка нужна т.к. значение является хорошим и означает, что вхождение найдено в самом начале строки (поиск успешен). Поэтому необходимо сравнивать именно с .

Флаги

Регулярные выражения могут иметь флаги, которые влияют на поиск.

В JavaScript их всего шесть:

С этим флагом поиск не зависит от регистра: нет разницы между и (см. пример ниже).
С этим флагом поиск ищет все совпадения, без него – только первое.
Многострочный режим (рассматривается в главе Многострочный режим якорей ^ $, флаг «m»).
Включает режим «dotall», при котором точка может соответствовать символу перевода строки (рассматривается в главе Символьные классы).
Включает полную поддержку юникода. Флаг разрешает корректную обработку суррогатных пар (подробнее об этом в главе Юникод: флаг «u» и класс \p{…}).
Режим поиска на конкретной позиции в тексте (описан в главе Поиск на заданной позиции, флаг «y»)

Цветовые обозначения

Здесь и далее в тексте используется следующая цветовая схема:

  • регулярное выражение –
  • строка (там где происходит поиск) –
  • результат –

Упрощённый пример

В чём же дело? Почему регулярное выражение «зависает»?

Чтобы это понять, упростим пример: уберём из него пробелы . Получится .

И, для большей наглядности, заменим на . Получившееся регулярное выражение тоже будет «зависать», например:

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

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

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

Что же происходит во время поиска в строке (укоротим для ясности), почему всё так долго?

  1. Первым делом, движок регулярных выражений пытается найти . Плюс является жадным по умолчанию, так что он хватает все цифры, какие может:

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

    Далее по шаблону ожидается конец строки , а в тексте символ , так что соответствий нет:

  2. Так как соответствие не найдено, то «жадный» квантификатор уменьшает количество повторений, возвращается на один символ назад.

    Теперь – это все цифры, за исключением последней:

  3. Далее движок снова пытается продолжить поиск, начиная уже с позиции ().

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

    Затем движок ожидает найти , но это ему не удаётся, ведь строка оканчивается на :

  4. Так как совпадения нет, то поисковый движок продолжает отступать назад. Общее правило таково: последний жадный квантификатор уменьшает количество повторений до тех пор, пока это возможно. Затем понижается предыдущий «жадный» квантификатор и т.д.

    Перебираются все возможные комбинации. Вот их примеры.

    Когда первое число содержит 7 цифр, а дальше число из 2 цифр:

    Когда первое число содержит 7 цифр, а дальше два числа по 1 цифре:

    Когда первое число содержит 6 цифр, а дальше одно число из 3 цифр:

    Когда первое число содержит 6 цифр, а затем два числа:

    …И так далее.

Существует много способов как разбить на числа набор цифр . Если быть точным, их , где – длина набора.

В случае их порядка миллиона, при – ещё в тысячу раз больше. На их перебор и тратится время.

Что же делать?

Может нам стоит использовать «ленивый» режим?

К сожалению, нет: если мы заменим на , то регулярное выражение всё ещё будет «зависать». Поменяется только порядок перебора, но не общее количество комбинаций.

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

Наборы и флаг «u»

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

Например, давайте попробуем найти шаблон в строке :

Результат неверный, потому что по умолчанию регулярные выражения «не знают» о существовании суррогатных пар.

Движок регулярных выражений думает, что – это не два, а четыре символа:

  1. левая половина от ,
  2. правая половина от ,
  3. левая половина от ,
  4. правая половина от .

Мы даже можем вывести их коды:

То есть в нашем примере выше ищется и выводится только левая половина от .

Если добавить флаг , то всё будет в порядке:

Аналогичная ситуация произойдёт при попытке искать диапазон: .

Если мы забудем флаг , то можем нечаянно получить ошибку:

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

При использовании флага шаблон будет работать правильно:

Флаги

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

/* Флаг - Значение */g – Глобальный поиск, не останавливается после нахождения первого совпадения.i – Игнорирование регистра (соответствует верхнему и нижнему регистрам).s - Точка (.) соответствует переводу на новую строку.m – Многострочный ввод, начинается с "^" и заканчивается "$" (начало и конец каждой строки).

Примеры:

// флаг g - Глобальный поискconst myPattern = /xyz/gconsole.log(myPattern.test('One xyz and one more xyz'))// true// флаг i - Игнорирование регистраconst myPattern = /xyz/iconsole.log(myPattern.test('XyZ'))// true - регистр символов не имеет значения при нечувствительном к регистру поиске.// флаг s - Точка (.) соответствует переводу на новую строкуconst myPattern = /foo.bar/sconsole.log(myPattern.test('foo\nbar'))// trueconsole.log(myPattern.test('foo bar'))// trueconsole.log(myPattern.test('foobar'))// false

Заключение

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

  • Чистый код JavaScript — объекты и классы
  • Хроники нового текстового редактора — от замысла до реализации
  • Двоичное дерево поиска: вставка значения с использованием JavaScript

Читайте нас в телеграмме, vk и

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

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

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

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

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

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

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

Все методы, кроме 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);
}

Заметки о методах

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

Search ()

Используется для нахождения позиции вхождения первого совпадения.

1
2
3
4
5
6
<script>
var regExp = /рыб/gi;
var text = "Покупайте речную рыбу!";
var myArray = text.search(regExp );
alert(myArray); //Ответ: 17
</script>

Match ()

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

1
2
3
4
5
6
7
8
<script>
var regExp = /12.02/;
var text = "11.02 - Концерт. 12.02 - Мастер-класс.";
var myArray = text.match(regExp );
alert( myArray );
alert( myArray.input ); //11.02 - Концерт. 12.02 - Мастер-класс.
alert( myArray.index ); //17
</script>

Split ()

Как и в некоторых других языках программирования, метод Split () разбивает значение строковой переменной на подстроки по заданному разделителю.

1
2
3
4
<script>
var text = "Пусть все будет хорошо";
alert(text.split(' ')); //Пусть,все,будет,хорошо
</script>

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

Replace ()

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

1
2
3
4
<script>
var text = "Ты пробежал 3 км за 13 и 25 минут.";
alert( text.replace( / и /g, "," )); // Ты пробежал 3 км за 13,25 минут
</script>

Exec ()

До этого все методы принадлежали к классу String. А оставшиеся два предоставляются классом RegExp.

Итак, текущий метод является дополнением к первым двум описанным методам. Он также ищет все вхождения и еще скобочные группы. Без указания флага g exec () работает, как match (). В противном случае совпадение запоминается, а его позиция записывается в lastIndex.

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  <script>
    var str = 'Сорок сорок сидели на трубе';
 
    var expresion = /сорок/ig;
    var res;
    alert( "lastIndex: " + expresion.lastIndex );
 
    while (res = expresion.exec(str)) {
      alert( 'Найдено: ' + res + ' на позиции: ' + res.index );
      alert( 'А теперь lastIndex равен: ' + expresion.lastIndex );
    }
 
    alert( 'Под конец lastIndex сбрасывается в: ' + expresion.lastIndex );
  </script>

Test ()

Данный инструмент проверяет, а есть ли хоть один результат совпадения строк. Если есть, то возвращает булево значение true, иначе – false.

1
2
3
4
<script>
var expresion  = /крас/gi;
alert( expresion.test("Ах, какая красна девица! красавица!")); //true
</script>

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

 
Прочитано: 145 раз

search()

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

// Синтаксис метода search()// 'проверяемый текст'.search(/шаблон/)// Создание текста для проверкиconst myString = 'The world of code is not full of code.'// Описание шаблонаconst myPattern = /code/// Использование search() для поиска//совпадения строки с шаблоном,//когда search() находит совпадениеmyString.search(myPattern)// -13// Вызов search() прямо на строке,// когда search() не находит совпадений'Another day in the life.'.search(myPattern)// -1

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

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

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

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

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

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

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

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

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

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

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

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

В действии:

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

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

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

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

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

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

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

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

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

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

Короткие обозначения

Для самых востребованных квантификаторов есть сокращённые формы записи:

Означает «один или более». То же самое, что и .

Например, находит числа (из одной или более цифр):

Означает «ноль или один». То же самое, что и . По сути, делает символ необязательным.

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

Поэтому шаблон найдёт два варианта: и :

Означает «ноль или более». То же самое, что и . То есть символ может повторяться много раз или вообще отсутствовать.

Например, шаблон находит цифру и все нули за ней (их может быть много или ни одного):

Сравните это с (один или более):

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

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

Adblock
detector