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

Шпаргалка представляет собой общее руководство по шаблонам регулярных выражений без учета специфики какого-либо языка. Она представлена в виде таблицы, помещающейся на одном печатном листе формата A4. Создана под лицензией Creative Commons на базе шпаргалки, автором которой является Dave Child ().

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

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

Здесь символ ^ обозначает начало строки. Без него шаблон соответствовал бы любой строке, содержащей цифру.

Символьные классы в регулярных выражениях соответствуют сразу некоторому набору символов. Например, \d соответствует любой цифре от 0 до 9 включительно, \w соответствует буквам и цифрам, а \W — всем символам, кроме букв и цифр. Шаблон, идентифицирующий буквы, цифры и пробел, выглядит так:

POSIX

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

Поначалу практически у всех возникают трудности с пониманием утверждений, однако познакомившись с ними ближе, вы будете использовать их довольно часто. Утверждения предоставляют способ сказать: «я хочу найти в этом документе каждое слово, включающее букву “q”, за которой не следует “werty”».

[^\s]*q(?!werty)[^\s]*

Приведенный выше код начинается с поиска любых символов, кроме пробела ([^\s]*), за которыми следует q . Затем парсер достигает «смотрящего вперед» утверждения. Это автоматически делает предшествующий элемент (символ, группу или символьный класс) условным — он будет соответствовать шаблону, только если утверждение верно. В нашем случае, утверждение является отрицательным (?!), т. е. оно будет верным, если то, что в нем ищется, не будет найдено.

Итак, парсер проверяет несколько следующих символов по предложенному шаблону (werty). Если они найдены, то утверждение ложно, а значит символ q будет «проигнорирован», т. е. не будет соответствовать шаблону. Если же werty не найдено, то утверждение верно, и с q все в порядке. Затем продолжается поиск любых символов, кроме пробела ([^\s]*).

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

Кванторы позволяют определить часть шаблона, которая должна повторяться несколько раз подряд. Например, если вы хотите выяснить, содержит ли документ строку из от 10 до 20 (включительно) букв «a», то можно использовать этот шаблон:

A{10,20}

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

".*"

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

Привет, Мир

Приведенный выше шаблон найдет в этой строке вот такую подстроку:

"helloworld.htm" title="Привет, Мир"

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

".*?"

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

"helloworld.htm" "Привет, Мир"

Регулярные выражения используют некоторые символы для обозначения различных частей шаблона. Однако, возникает проблема, если вам нужно найти один из таких символов в строке, как обычный символ. Точка, к примеру, в регулярном выражении обозначает «любой символ, кроме переноса строки». Если вам нужно найти точку в строке, вы не можете просто использовать « . » в качестве шаблона — это приведет к нахождению практически всего. Итак, вам необходимо сообщить парсеру, что эта точка должна считаться обычной точкой, а не «любым символом». Это делается с помощью знака экранирования.

Знак экранирования, предшествующий символу вроде точки, заставляет парсер игнорировать его функцию и считать обычным символом. Есть несколько символов, требующих такого экранирования в большинстве шаблонов и языков. Вы можете найти их в правом нижнем углу шпаргалки («Мета-символы»).

Шаблон для нахождения точки таков:

\.

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

Подстановка строк подробно описана в следующем параграфе «Группы и диапазоны», однако здесь следует упомянуть о существовании «пассивных» групп. Это группы, игнорируемые при подстановке, что очень полезно, если вы хотите использовать в шаблоне условие «или», но не хотите, чтобы эта группа принимала участие в подстановке.

Группы и диапазоны очень-очень полезны. Вероятно, проще будет начать с диапазонов. Они позволяют указать набор подходящих символов. Например, чтобы проверить, содержит ли строка шестнадцатеричные цифры (от 0 до 9 и от A до F), следует использовать такой диапазон:

Чтобы проверить обратное, используйте отрицательный диапазон, который в нашем случае подходит под любой символ, кроме цифр от 0 до 9 и букв от A до F:

[^A-Fa-f0-9]

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

Использовать «или» очень просто: следующий шаблон ищет «ab» или «bc»:

Если в регулярном выражении необходимо сослаться на какую-то из предшествующих групп, следует использовать \n , где вместо n подставить номер нужной группы. Вам может понадобиться шаблон, соответствующий буквам «aaa» или «bbb», за которыми следует число, а затем те же три буквы. Такой шаблон реализуется с помощью групп:

(aaa|bbb)+\1

Первая часть шаблона ищет «aaa» или «bbb», объединяя найденные буквы в группу. За этим следует поиск одной или более цифр (+), и наконец \1 . Последняя часть шаблона ссылается на первую группу и ищет то же самое. Она ищет совпадение с текстом, уже найденным первой частью шаблона, а не соответствующее ему. Таким образом, «aaa123bbb» не будет удовлетворять вышеприведенному шаблону, так как \1 будет искать «aaa» после числа.

Одним из наиболее полезных инструментов в регулярных выражениях является подстановка строк. При замене текста можно сослаться на найденную группу, используя $n . Скажем, вы хотите выделить в тексте все слова «wish» жирным начертанием. Для этого вам следует использовать функцию замены по регулярному выражению, которая может выглядеть так:

Replace(pattern, replacement, subject)

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

([^A-Za-z0-9])(wish)([^A-Za-z0-9])

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

$1$2$3

Ею будет заменена вся найденная по шаблону строка. Мы начинаем замену с первого найденного символа (который не буква и не цифра), отмечая его $1 . Без этого мы бы просто удалили этот символ из текста. То же касается конца подстановки ($3). В середину мы добавили HTML тег для жирного начертания (разумеется, вместо него вы можете использовать CSS или ), выделив им вторую группу, найденную по шаблону ($2).

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

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

/pattern/

Модификаторы добавляются в конец этой строки, вот так:

/pattern/i

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

Реально спасибо. особенно за разъяснения. Это пожалуйста:) огромное спасибо. спасибо огроменное вам! Спасибо Классная серия... я кстати перевожу с английского эту серию (и делаю в HTML формате), у меня на сайте можете посмотреть: sitemaker.x10.bz. Там есть и шпаргалка по HTML, которой здесь нет. Спасибо. А как на счёт убрать первые 10 символов любых и затем будет какой-то текст с символами, и дальше с определенного символа надо будет убрать всё до конца. !? 2 lails: Здесь регулярные выражения не нужны. Вам помогут substr() и strpos(), если речь о PHP, или их аналоги в других языках. Интересно было про утверждения почитать, понемогу начинаю понимать. Вот так нагляднее будет: http://pcreonline.com/OazZNu/ Здравствуйте. Подскажите пожалуйста - почему у меня в FireFox не работают "смотрящие назад утверждения"? В справке RegExp Мозиллы их вообще нет, неужели в Лисе это невозможно? =((( Доброе утро, смотрящие назад утверждения не поддерживаются JavaScript"ом, поэтому в других браузерах по всей вероятности тоже не будут работать. По этой ссылке есть более детальная информация об ограничениях регулярок в языке JavaScript. Молодца! давай пятюню! Спасибо! Кратко и наглядно! Хм. Пасиба) Спасибо! спасибо, очень помогло спасибо большое! Спасибо за статью! Подскажите, а если нужно ограничить ввод пароля цифрами и вводом не более 5 букв? Здравствуйте, шпаргалка всем хороша, но можно было-бы сделать зебру посветлей, потому что когда печатаешь чёрные буквы на тёмном фоне не очень Спасибо. Небольшой вопрос, нужно найти значения между start= и &, но при этом исключить данные границы диапазона из выдачи. Как найти диапазон сделал: start=.{1,}&
А вот как исключить границы, знаний пока не хватает. Буду благодарен за помощь. Подскажите пожалуйста, как задать регулярное выражение на проверку (может быть, а может и не быть совпадение) ? Как правильно записать регулярку начинается со знака равно, находит любой текст внутри и останавливается на знаке &
Эти знаки не включены в поиск с них начинается и заканчивается нужная часть строки...

Пишу несколькими способами, но в результате либо остается весь текст, но исчезают знаки = и &
Или остается знак & в конце строки...
Читал про доллар он не удаляет символ в конце строки

небольшой пример

var reg = /[^=]*[^&]/g
str.match(reg);

По логике мы начинаем со знака равенства и ищем любой текст /[^=]*
далее останавливаемся на знаке & [^&] не включая его в поиск и повторяем поиск дольше пока не обойдем его полностью /g

Не работает... Возвращает полностью строку

Добрый вечер, подскажите, как найти число, которое меньше 20? Спасибо ребята Спасибо за статью! Подскажите, а если нужно ограничить ввод пароля цифрами и вводом не более 5 букв?

Дима @ 24 апреля 2015
Ответ:((?=.*\d)(?=.*)(?=.*).{8,15})--- в конце вместо 8 просто поставьте 5

Всем привет, я начинаю только...
Не могли бы вы мне подсказать, что означает:
/^\w\w/a
Буду очень благодарен) Здравствуйте, подскажите как перечислите все цифры в данном выражении через пробел 9*2 Божественная шпаргалка! Сняла все вопросы:-) {M1}
{M2}
{M3}
{M4}
{M5}

Подскажите как написать выражение чтобы найти где встречается в тексте

Спасибо!

Модификаторы

Символ «минус» (-) меред модификатором (за исключением U) создаёт его отрицание.

Спецсимволы

Аналог Описание
() подмаска, вложенное выражение
групповой символ
{a,b} количество вхождений от «a» до «b»
| логическое «или», в случае с односимвольными альтернативами используйте
\ экранирование спец символа
. любой сивол, кроме перевода строки
\d десятичная цифра
\D [^\d] любой символ, кроме десятичной цифры
\f конец (разрыв) страницы
\n перевод строки
\pL буква в кодировке UTF-8 при использовании модификатора u
\r возврат каретки
\s [ \t\v\r\n\f] пробельный символ
\S [^\s] любой символ, кроме промельного
\t табуляция
\w любая цифра, буква или знак подчеркивания
\W [^\w] любой символ, кроме цифры, буквы или знака подчеркивания
\v вертикальная табуляция

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

Позиция внутри строки

Пример Соответствие Описание
^ ^a a aa aaa начало строки
$ a$ aaa aaa конец строки
\A \Aa a aa aaa
aaa aaa
начало текста
\z a\z aaa aaa
aaa aaa
конец текста
\b a\b
\ba
aaa aaa
a aa a aa
граница слова, утверждение: предыдущий символ словесный, а следующий - нет, либо наоборот
\B \Ba\B aa a aa a отсутствие границы слова
\G \Ga aaa aaa Предыдущий успешный поиск, поиск остановился на 4-й позиции — там, где не нашлось a
Скачать в PDF , PNG .

Якоря

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

Здесь символ ^ обозначает начало строки. Без него шаблон соответствовал бы любой строке, содержащей цифру.

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

Символьные классы в регулярных выражениях соответствуют сразу некоторому набору символов. Например, \d соответствует любой цифре от 0 до 9 включительно, \w соответствует буквам и цифрам, а \W — всем символам, кроме букв и цифр. Шаблон, идентифицирующий буквы, цифры и пробел, выглядит так:

POSIX

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

Утверждения

Поначалу практически у всех возникают трудности с пониманием утверждений, однако познакомившись с ними ближе, вы будете использовать их довольно часто. Утверждения предоставляют способ сказать: «я хочу найти в этом документе каждое слово, включающее букву “q”, за которой не следует “werty”».

[^\s]*q(?!werty)[^\s]*

Приведенный выше код начинается с поиска любых символов, кроме пробела ([^\s]*), за которыми следует q . Затем парсер достигает «смотрящего вперед» утверждения. Это автоматически делает предшествующий элемент (символ, группу или символьный класс) условным — он будет соответствовать шаблону, только если утверждение верно. В нашем случае, утверждение является отрицательным (?!), т. е. оно будет верным, если то, что в нем ищется, не будет найдено.

Итак, парсер проверяет несколько следующих символов по предложенному шаблону (werty). Если они найдены, то утверждение ложно, а значит символ q будет «проигнорирован», т. е. не будет соответствовать шаблону. Если же werty не найдено, то утверждение верно, и с q все в порядке. Затем продолжается поиск любых символов, кроме пробела ([^\s]*).

Кванторы

Кванторы позволяют определить часть шаблона, которая должна повторяться несколько раз подряд. Например, если вы хотите выяснить, содержит ли документ строку из от 10 до 20 (включительно) букв «a», то можно использовать этот шаблон:

A{10,20}

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

".*"

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

Привет, Мир

Приведенный выше шаблон найдет в этой строке вот такую подстроку:

"helloworld.htm" title="Привет, Мир"

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

".*?"

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

"helloworld.htm" "Привет, Мир"

Экранирование в регулярных выражениях

Регулярные выражения используют некоторые символы для обозначения различных частей шаблона. Однако, возникает проблема, если вам нужно найти один из таких символов в строке, как обычный символ. Точка, к примеру, в регулярном выражении обозначает «любой символ, кроме переноса строки». Если вам нужно найти точку в строке, вы не можете просто использовать « . » в качестве шаблона — это приведет к нахождению практически всего. Итак, вам необходимо сообщить парсеру, что эта точка должна считаться обычной точкой, а не «любым символом». Это делается с помощью знака экранирования.

Знак экранирования, предшествующий символу вроде точки, заставляет парсер игнорировать его функцию и считать обычным символом. Есть несколько символов, требующих такого экранирования в большинстве шаблонов и языков. Вы можете найти их в правом нижнем углу шпаргалки («Мета-символы»).

Шаблон для нахождения точки таков:

\.

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

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

Подстановка строк

Подстановка строк подробно описана в следующем параграфе «Группы и диапазоны», однако здесь следует упомянуть о существовании «пассивных» групп. Это группы, игнорируемые при подстановке, что очень полезно, если вы хотите использовать в шаблоне условие «или», но не хотите, чтобы эта группа принимала участие в подстановке.

Группы и диапазоны

Группы и диапазоны очень-очень полезны. Вероятно, проще будет начать с диапазонов. Они позволяют указать набор подходящих символов. Например, чтобы проверить, содержит ли строка шестнадцатеричные цифры (от 0 до 9 и от A до F), следует использовать такой диапазон:

Чтобы проверить обратное, используйте отрицательный диапазон, который в нашем случае подходит под любой символ, кроме цифр от 0 до 9 и букв от A до F:

[^A-Fa-f0-9]

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

Использовать «или» очень просто: следующий шаблон ищет «ab» или «bc»:

Если в регулярном выражении необходимо сослаться на какую-то из предшествующих групп, следует использовать \n , где вместо n подставить номер нужной группы. Вам может понадобиться шаблон, соответствующий буквам «aaa» или «bbb», за которыми следует число, а затем те же три буквы. Такой шаблон реализуется с помощью групп:

(aaa|bbb)+\1

Первая часть шаблона ищет «aaa» или «bbb», объединяя найденные буквы в группу. За этим следует поиск одной или более цифр (+), и наконец \1 . Последняя часть шаблона ссылается на первую группу и ищет то же самое. Она ищет совпадение с текстом, уже найденным первой частью шаблона, а не соответствующее ему. Таким образом, «aaa123bbb» не будет удовлетворять вышеприведенному шаблону, так как \1 будет искать «aaa» после числа.

Одним из наиболее полезных инструментов в регулярных выражениях является подстановка строк. При замене текста можно сослаться на найденную группу, используя $n . Скажем, вы хотите выделить в тексте все слова «wish» жирным начертанием. Для этого вам следует использовать функцию замены по регулярному выражению, которая может выглядеть так:

Replace(pattern, replacement, subject)

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

([^A-Za-z0-9])(wish)([^A-Za-z0-9])

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

$1$2$3

Ею будет заменена вся найденная по шаблону строка. Мы начинаем замену с первого найденного символа (который не буква и не цифра), отмечая его $1 . Без этого мы бы просто удалили этот символ из текста. То же касается конца подстановки ($3). В середину мы добавили HTML тег для жирного начертания (разумеется, вместо него вы можете использовать CSS или ), выделив им вторую группу, найденную по шаблону ($2).

Модификаторы шаблонов

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

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

/pattern/

Модификаторы добавляются в конец этой строки, вот так:

/pattern/i

Мета-символы

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

Шпаргалка представляет собой общее руководство по шаблонам регулярных выражений без учета специфики какого-либо языка. Она представлена в виде таблицы, помещающейся на одном печатном листе формата A4. Создана под лицензией Creative Commons на базе шпаргалки, автором которой является Dave Child. Скачать в PDF , PNG .


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

Синтаксис:

//Первый вариант создания регулярного выражения 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);

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

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

Регулярные выражения (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”, можно написать rm d* .

Регулярные выражения представляют собой похожий, но гораздо более сильный инструмент для поиска строк, проверки их на соответствие какому-либо шаблону и другой подобной работы. Англоязычное название этого инструмента - Regular Expressions или просто RegExp . Строго говоря, регулярные выражения - специальный язык для описания шаблонов строк.

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

Основы синтаксиса

В первую очередь стоит заметить, что любая строка сама по себе является регулярным выражением. Так, выражению Хаха, очевидно, будет соответствовать строка “Хаха” и только она. Регулярные выражения являются регистрозависимыми, поэтому строка “хаха” (с маленькой буквы) уже не будет соответствовать выражению выше.

Однако уже здесь следует быть аккуратным - как и любой язык, регулярные выражения имеют спецсимволы, которые нужно экранировать. Вот их список: . ^ $ * + ? { } \ | () . Экранирование осуществляется обычным способом - добавлением \ перед спецсимволом.

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

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

Здесь нам на помощь придут наборы - вместо указания конкретного символа, мы можем записать целый список, и если в исследуемой строке на указанном месте будет стоять любой из перечисленных символов, строка будет считаться подходящей. Наборы записываются в квадратных скобках - паттерну будет соответствовать любой из символов “a”, “b”, “c” или “d”.

Внутри набора бо льшая часть спецсимволов не нуждается в экранировании, однако использование \ перед ними не будет считаться ошибкой. По прежнему необходимо экранировать символы “\” и “^”, и, желательно, “]” (так, обозначает любой из символов “]” или «[», тогда как [х] – исключительно последовательность “[х]”). Необычное на первый взгляд поведение регулярок с символом “]” на самом деле определяется известными правилами, но гораздо легче просто экранировать этот символ, чем их запоминать. Кроме этого, экранировать нужно символ «-», он используется для задания диапазонов (см. ниже).

Если сразу после [ записать символ ^ , то набор приобретёт обратный смысл - подходящим будет считаться любой символ кроме указанных. Так, паттерну [^xyz] соответствует любой символ, кроме, собственно, “x”, “y” или “z”.

Итак, применяя данный инструмент к нашему случаю, если мы напишем [Хх][аоие]х[аоие] , то каждая из строк “Хаха”, “хехе”, “хихи” и даже “Хохо” будут соответствовать шаблону.

Предопределённые классы символов

Для некоторых наборов, которые используются достаточно часто, существуют специальные шаблоны. Так, для описания любого пробельного символа (пробел, табуляция, перенос строки) используется \s , для цифр - \d , для символов латиницы, цифр и подчёркивания “_” - \w .

Если необходимо описать вообще любой символ, для этого используется точка - . . Если указанные классы написать с заглавной буквы (\S , \D , \W) то они поменяют свой смысл на противоположный - любой непробельный символ, любой символ, который не является цифрой, и любой символ кроме латиницы, цифр или подчёркивания соответственно.

Также с помощью регулярных выражений есть возможность проверить положение строки относительно остального текста. Выражение \b обозначает границу слова, \B - не границу слова, ^ - начало текста, а $ - конец. Так, по паттерну \bJava\b в строке “Java and JavaScript” найдутся первые 4 символа, а по паттерну \bJava\B - символы c 10-го по 13-й (в составе слова “JavaScript”).

Диапазоны

У вас может возникнуть необходимость обозначить набор, в который входят буквы, например, от “б” до “ф”. Вместо того, чтобы писать [бвгдежзиклмнопрстуф] можно воспользоваться механизмом диапазонов и написать [б-ф] . Так, паттерну x соответствует строка “xA6”, но не соответствует “xb9” (во-первых, из-за того, что в диапазоне указаны только заглавные буквы, во-вторых, из-за того, что 9 не входит в промежуток 0-8).

Механизм диапазонов особенно актуален для русского языка, ведь для него нет конструкции, аналогичной \w . Чтобы обозначить все буквы русского алфавита, можно использовать паттерн [а-яА-ЯёЁ] . Обратите внимание, что буква “ё” не включается в общий диапазон букв, и её нужно указывать отдельно.

Квантификаторы (указание количества повторений)

Вернёмся к нашему примеру. Что, если в “смеющемся” междометии будет больше одной гласной между буквами “х”, например “Хаахаааа”? Наша старая регулярка уже не сможет нам помочь. Здесь нам придётся воспользоваться квантификаторами.

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

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

Таким образом, с помощью квантификаторов мы можем улучшить наш шаблон для междометий до [Хх][аоеи]+х[аоеи]* , и он сможет распознавать строки “Хааха”, “хееееех” и “Хихии”.

Ленивая квантификация

Предположим, перед нами стоит задача - найти все HTML-теги в строке

Tproger - мой любимый сайт о программировании!

Очевидное решение <.*> здесь не сработает - оно найдёт всю строку целиком, т.к. она начинается с тега абзаца и им же заканчивается. То есть содержимым тега будет считаться строка

P>Tproger - мой любимый сайт о программировании!

Это происходит из-за того, что по умолчанию квантификатор работают по т.н. жадному алгоритму - старается вернуть как можно более длинную строку, соответствующую условию. Решить проблему можно двумя способами. Первый - использовать выражение <[^>]*> , которое запретит считать содержимым тега правую угловую скобку. Второй - объявить квантификатор не жадным, а ленивым . Делается это с помощью добавления справа к квантификатору символа? . Т.е. для поиска всех тегов выражение обратится в <.*?> .

Ревнивая квантификация

Иногда для увеличения скорости поиска (особенно в тех случаях, когда строка не соответствует регулярному выражению) можно использовать запрет алгоритму возвращаться к предыдущим шагам поиска для того, чтобы найти возможные соответствия для оставшейся части регулярного выражения. Это называется ревнивой квантификацией. Квантификатор делается ревнивым с помощью добавления к нему справа символа + . Ещё одно применение ревнивой квантификации - исключение нежелательных совпадений. Так, паттерну ab*+a в строке “ababa” будут соответствовать только первые три символа, но не символы с третьего по пятый, т.к. символ “a”, который стоит на третьей позиции, уже был использован для первого результата.

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

Для нашего шаблона “смеющегося” междометия осталась самая малость - учесть, что буква “х” может встречаться более одного раза, например, “Хахахахааахахооо”, а может и вовсе заканчиваться на букве “х”. Вероятно, здесь нужно применить квантификатор для группы [аиое]+х, но если мы просто напишем [аиое]х+ , то квантификатор + будет относиться только к символу “х”, а не ко всему выражению. Чтобы это исправить, выражение нужно взять в круглые скобки: ([аиое]х)+ .

Таким образом, наше выражение превращается в [Хх]([аиое]х?)+ - сначала идёт заглавная или строчная “х”, а потом произвольное ненулевое количество гласных, которые (возможно, но не обязательно) перемежаются одиночными строчными “х”. Однако это выражение решает проблему лишь частично - под это выражение попадут и такие строки, как, например, “хихахех” - кто-то может быть так и смеётся, но допущение весьма сомнительное. Очевидно, мы можем использовать набор из всех гласных лишь единожды, а потом должны как-то опираться на результат первого поиска. Но как?…

Запоминание результата поиска по группе (обратная связь)

Оказывается, результат поиска по скобочной группе записывается в отдельную ячейку памяти, доступ к которой доступен для использования в последующих частях регулярного выражения. Возвращаясь к задаче с поиском HTML-тегов на странице, нам может понадобиться не только найти теги, но и узнать их название. В этом нам может помочь регулярное выражение <(.*?)> .

Tproger - мой любимый сайт о программировании!

Результат поиска по всем регулярному выражению: “

”, “”, “”, “”, “”, “

”.
Результат поиска по первой группе: “p”, “b”, “/b”, “i”, “/i”, “/i”, “/p”.

На результат поиска по группе можно ссылаться с помощью выражения \n , где n - цифра от 1 до 9. Например выражению (\w)(\w)\1\2 соответствуют строки “aaaa”, “abab”, но не соответствует “aabb”.

Если выражение берётся в скобки только для применения к ней квантификатора (не планируется запоминать результат поиска по этой группе), то сразу первой скобки стоит добавить?: , например (?:+\w) .

С использованием этого механизма мы можем переписать наше выражение к виду [Хх]([аоие])х?(?:\1х?)* .

Перечисление

Чтобы проверить, удовлетворяет ли строка хотя бы одному из шаблонов, можно воспользоваться аналогом булевого оператора OR, который записывается с помощью символа | . Так, под шаблон Анна|Одиночество попадают строки “Анна” и “Одиночество” соответственно. Особенно удобно использовать перечисления внутри скобочных групп. Так, например (?:a|b|c|d) полностью эквивалентно (в данном случае второй вариант предпочтительнее в силу производительности и читаемости).

error: Content is protected !!