Регулярні вирази
Содержание:
- Найти все / Заменить все
- Жадность
- Методы RegExp
- Флаги регулярных выражений
- Правила написания шаблонов в JavaScript
- Составление регулярных выражений
- Экранирование внутри […]
- Точка – это любой символ
- Примеры
- Применение регулярного выражения для строки
- Найти все / Заменить все
- Флаги
- Упрощённый пример
- Наборы и флаг «u»
- Флаги
- Заключение
- Назад к словам и строкам
- Строковые методы, поиск и замена
- Заметки о методах
- search()
- Содержимое скобок в match
- Короткие обозначения
Найти все / Заменить все
Эти две задачи решаются в 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»)
Цветовые обозначения
Здесь и далее в тексте используется следующая цветовая схема:
- регулярное выражение –
- строка (там где происходит поиск) –
- результат –
Упрощённый пример
В чём же дело? Почему регулярное выражение «зависает»?
Чтобы это понять, упростим пример: уберём из него пробелы . Получится .
И, для большей наглядности, заменим на . Получившееся регулярное выражение тоже будет «зависать», например:
В чём же дело, что не так с регулярным выражением?
Внимательный читатель, посмотрев на , наверняка удивится, ведь оно какое-то странное. Квантификатор здесь выглядит лишним. Если хочется найти число, то с тем же успехом можно искать .
Действительно, это регулярное выражение носит искусственный характер, но, разобравшись с ним, мы поймём и практический пример, данный выше. Причина их медленной работы одинакова. Поэтому оставим как есть.
Что же происходит во время поиска в строке (укоротим для ясности), почему всё так долго?
-
Первым делом, движок регулярных выражений пытается найти . Плюс является жадным по умолчанию, так что он хватает все цифры, какие может:
Затем движок пытается применить квантификатор , но больше цифр нет, так что звёздочка ничего не даёт.
Далее по шаблону ожидается конец строки , а в тексте символ , так что соответствий нет:
-
Так как соответствие не найдено, то «жадный» квантификатор уменьшает количество повторений, возвращается на один символ назад.
Теперь – это все цифры, за исключением последней:
-
Далее движок снова пытается продолжить поиск, начиная уже с позиции ().
Звёздочка теперь может быть применена – она даёт второе число :
Затем движок ожидает найти , но это ему не удаётся, ведь строка оканчивается на :
-
Так как совпадения нет, то поисковый движок продолжает отступать назад. Общее правило таково: последний жадный квантификатор уменьшает количество повторений до тех пор, пока это возможно. Затем понижается предыдущий «жадный» квантификатор и т.д.
Перебираются все возможные комбинации. Вот их примеры.
Когда первое число содержит 7 цифр, а дальше число из 2 цифр:
Когда первое число содержит 7 цифр, а дальше два числа по 1 цифре:
Когда первое число содержит 6 цифр, а дальше одно число из 3 цифр:
Когда первое число содержит 6 цифр, а затем два числа:
…И так далее.
Существует много способов как разбить на числа набор цифр . Если быть точным, их , где – длина набора.
В случае их порядка миллиона, при – ещё в тысячу раз больше. На их перебор и тратится время.
Что же делать?
Может нам стоит использовать «ленивый» режим?
К сожалению, нет: если мы заменим на , то регулярное выражение всё ещё будет «зависать». Поменяется только порядок перебора, но не общее количество комбинаций.
Некоторые движки регулярных выражений содержат хитрые проверки и конечные автоматы, которые позволяют избежать полного перебора в таких ситуациях или кардинально ускорить его, но не все движки и не всегда.
Наборы и флаг «u»
Если в наборе есть суррогатные пары, для корректной работы обязательно нужен флаг .
Например, давайте попробуем найти шаблон в строке :
Результат неверный, потому что по умолчанию регулярные выражения «не знают» о существовании суррогатных пар.
Движок регулярных выражений думает, что – это не два, а четыре символа:
- левая половина от ,
- правая половина от ,
- левая половина от ,
- правая половина от .
Мы даже можем вывести их коды:
То есть в нашем примере выше ищется и выводится только левая половина от .
Если добавить флаг , то всё будет в порядке:
Аналогичная ситуация произойдёт при попытке искать диапазон: .
Если мы забудем флаг , то можем нечаянно получить ошибку:
Причина в том, что без флага суррогатные пары воспринимаются как два символа, так что воспринимается как (каждая суррогатная пара заменена на коды). Теперь уже отлично видно, что диапазон некорректен: его левая граница больше правой, это и есть формальная причина ошибки.
При использовании флага шаблон будет работать правильно:
Флаги
Флаги — последний тип символов, которые используются в регулярных выражениях. С помощью флагов можно легко расширить функционал шаблонов. К примеру, флаги позволяют игнорировать регистр букв, чтобы шаблон находил совпадения и в верхнем, и в нижнем регистрах, находить множественные совпадения и совпадения в многострочном тексте и т. д.
/* Флаг - Значение */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
Скобочные группы нумеруются слева направо. Поисковый движок запоминает содержимое, которое соответствует каждой скобочной группе, и позволяет получить его в результате.
Метод , если у регулярного выражения нет флага , ищет первое совпадение и возвращает его в виде массива:
- На позиции будет всё совпадение целиком.
- На позиции – содержимое первой скобочной группы.
- На позиции – содержимое второй скобочной группы.
- …и так далее…
Например, мы хотим найти HTML теги и обработать их. Было бы удобно иметь содержимое тега (то, что внутри уголков) в отдельной переменной.
Давайте заключим внутреннее содержимое в круглые скобки: .
Теперь получим как тег целиком , так и его содержимое в виде массива:
Скобки могут быть и вложенными.
Например, при поиске тега в нас может интересовать:
- Содержимое тега целиком: .
- Название тега: .
- Атрибуты тега: .
Заключим их в скобки в шаблоне: .
Вот их номера (слева направо, по открывающей скобке):
В действии:
По нулевому индексу в всегда идёт полное совпадение.
Затем следуют группы, нумеруемые слева направо, по открывающим скобкам. Группа, открывающая скобка которой идёт первой, получает первый индекс в результате – . Там находится всё содержимое тега.
Затем в идёт группа, образованная второй открывающей скобкой – имя тега, далее в будет остальное содержимое тега: .
Соответствие для каждой группы в строке:
Даже если скобочная группа необязательна (например, стоит квантификатор ), соответствующий элемент массива существует и равен .
Например, рассмотрим регулярное выражение . Оно ищет букву , за которой идёт необязательная буква , за которой, в свою очередь, идёт необязательная буква .
Если применить его к строке из одной буквы , то результат будет такой:
Массив имеет длину , но все скобочные группы пустые.
А теперь более сложная ситуация для строки :
Длина массива всегда равна . Для группы ничего нет, поэтому результат: .
Короткие обозначения
Для самых востребованных квантификаторов есть сокращённые формы записи:
-
Означает «один или более». То же самое, что и .
Например, находит числа (из одной или более цифр):
-
Означает «ноль или один». То же самое, что и . По сути, делает символ необязательным.
Например, шаблон найдёт после которого, возможно, следует , а затем .
Поэтому шаблон найдёт два варианта: и :
-
Означает «ноль или более». То же самое, что и . То есть символ может повторяться много раз или вообще отсутствовать.
Например, шаблон находит цифру и все нули за ней (их может быть много или ни одного):
Сравните это с (один или более):