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

05.08.2019 Программы и сервисы

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

Вы когда-нибудь работали со строками? Да-да, с теми самыми «массивами символов», которые мы все знаем и любим. Если вы программировали на чем-нибудь, кроме чистого С, с уверенностью можно предположить, что работали, причем не раз. Но что, если вы имеете дело со множеством строк? Или со строками, которые сгенерированы не вашей программой? Например, вы считываете электронное письмо, парсите аргументы командной строки или читаете инструкции, написанные человеком, и вам нужен более структурированный метод работы со всем этим.

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

Введение. Регулярное выражение

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

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

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

Введение. Regex

Сейчас, возможно, мы подошли к месту, где пора испугаться (если вы до сих пор этого не сделали). Мы рассмотрим различия между тем, что вкладывается в понятие регулярных выражений языками программирования, а что - фундаментальной информатикой.

  • Регулярные выражения с точки зрения информатики - правила, объясняющие формальный язык.
  • Регулярные выражения с точки зрения языков программирования - грамматика, выражающая, в большей степени, некоторый контекстно-зависимый язык .

Контекстно-зависимые языки ощутимо сложнее и мощнее, так что с этого момента условимся называть регулярные выражения в терминах языков программирования „regex“, дабы подчеркнуть их обособленность от формальных языков в целом.

Учимся писать regex-ы

Регулярные выражения описываются с помощью двух слэшей (// ) и соответствуют строкам, подходящим под шаблон, заключенный между ними. Например, /Hi/ соответствует „Hi“, так что мы можем проверить соответствие некоторой строки этому шаблону.

Символы в регулярных выражениях сопоставляются в том порядке, в котором вводятся. Так /Hello world/ отвечает строке „Hello world“.

Можно упростить поиск произвольных слов, добавив немного regex-магии: \w соответствует любому «слову», составленному только из букв. По такому же принципу идентифицируются числа: \d .

Пример 1

Превосходно, теперь мы можем сравнивать строки или проверять их соответствие некоторому паттерну. Что дальше? Могут ли регулярные выражения выполнять еще какие-нибудь функции?

Будьте уверены! Скажем, мы написали IRC чат бота, который реагирует, если кто-то напишет „Josh“. Наш бот сканирует каждое сообщение, пока не дождется совпадения. Тогда бот отвечает: „Woah, I hope you aren’t talking bad about my pal Josh!“ («О, надеюсь, вы не будете говорить плохо о моем приятеле Джоше!»). Потому что с Джошами дружат только роботы.

Для сравнения строк наш бот использует шаблон /Josh/ . В один прекрасный момент некто по имени Eli обронит: „Eli: Josh, do you really need that much caffeine?“ («Эли: Джош, тебе действительно необходимо такое количество кофеина?»). Наш бот навострит ушки, обнаружит совпадение, выдаст свой неожиданный ответ, чем достаточно напугает Эли. Миссия выполнена! Или нет?

Что, если бы наш бот был более умным? Что, если бы он, например, обращался к говорящему по имени? Что-нибудь вроде „Woah, I hope you aren’t bad-mouthing my buddy Josh, Eli.“ («О, надеюсь, ты не будешь злословить о моем приятеле Джоше, Эли?»).

Квантификаторы (повторяющиеся символы)

0 и более

Мы можем сделать это… Но для начала нужно уяснить пару моментов. Первый - квантификаторы (для повторяющихся символов). Можно использовать * , чтобы обозначить 0 или несколько символов после. Например, /a*/ может соответствовать „aaaaaaa“, а также „“. Да, вы не ослышались: оно будет отвечать пустой строке.

* служит для обозначения чего-то необязательного, так как символ, которому она соответствует, существовать вовсе не обязан. Но он может. И не раз (теоретически, бесчисленное множество раз).
Можно обозначить „Josh“ с помощью /Josh/ , но мы можем также задать „Jjjjjjjjjosh“ или „osh“ паттерном /J*osh/ .

1 и более

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

Таким образом, мы можем задать шаблоном /J+osh/ строки „Josh“ или „Jjjjjjjjjosh“, но не „osh“.

Метасимволы

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

Но что, если он злится настолько сильно, что даже пару раз ударил лицом по клавиатуре? Как нам обозначить «ааавыопшадлорвпт», не зная заранее, насколько меток его нос?
С помощью метасимволов !

Метасимволы позволяют задавать абсолютно ЧТО УГОДНО. Их синтаксис — . . (Да, точка. Просто точка.). Бьемся об заклад, вы часто пользуетесь ею, так что не стесняйтесь обозначать ей конец предложения.

Можно задать „Joooafhuaisggsh“ выражением /Jo+.*sh/ , комбинируя полученные ранее знания о повторяющихся символах и метасимволах. Если быть точными, данное выражение соответствует одной „J“, одному или более „o“, нулю или нескольким метасимволам, а также одной „s“ и одной „h“. Эти пять блоков подводят нас к тому, что мы называем…

…группами символов

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

Это полезно понять и как отдельную технику, но большую функциональность она обретает в сочетании с повторяющимися символами. Группы символов задаются с помощью круглых скобок (да-да, этих ребят).
Допустим, мы хотим повторять „Jos“, но не „h“. что-то вроде „JosJosJosJosJosh“. Это можно сделать выражением /(Jos)+h/ . Просто, не правда ли?

Но наконец… Возвращаясь к нашему первому примеру, как нам получить имя Эли в нашем IRC чате из отправленного ею сообщения?

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

Например, /(.+) \1/ — особый случай. Здесь мы видим набор случайных символов, повторяющийся один или более раз, пробел после него, а затем повторение точно такого же набора еще раз. Так что такое выражение будет соответствовать „abc abc“, но не „abc def“, даже если „def“ сам по себе отвечает (.*) .

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

Пример 2

Фух… Наконец-то можно вернуться к примеру с IRC чат ботом. Давайте применим наши знания на практике.

Если мы хотим выцепить имя отправителя сообщения, когда он пишет „Josh“, наше выражение будет выглядеть примерно так: /(\w+): .*Josh.*/ , и мы сможем сохранить результат в переменной в нашем языке программирования для ответа.

Давайте рассмотрим наше регулярное выражение. Здесь одна или более букв, следующих за «: », 0 или более символов, „Josh“ и снова 0 или более символов.

Заметка: /.*word.*/ — простой способ задать строку, содержащую „word“, причем другие символы в ней могут присутствовать, а могут и нет.

На Python это будет выглядеть следующим образом:
import re
pattern = re.compile(ur"(\w+): .*Josh.*") # Our regex
string = u"Eli: Josh go move your laundry" # Our string
matches = re.match(pattern, string) # Test the string
who = matches.group(1) # Get who said the message
print(who) # "Eli"
Заметьте, что мы использовали .group(1) точно так же, как \1 . В этом нет ничего нового, за исключением использования регулярных выражений в Питоне.

Начало и конец

До этого момента мы предполагали, что искомые подстроки могут находиться в любом месте строки. К примеру, /(Jos)+h/ соответствует любой строке, которая содержит „Jos-повторяющееся-h“ в произвольном месте.

А что, если нам необходимо, чтобы строка начиналась с этого шаблона? Это можно обозначить как /^(Jos)+h/ , где ^ соответствует началу строки. Аналогично, $ обозначает конец строки.

Теперь, если мы хотим задать строку, содержащую только „Jos-повторяющееся-h“, то напишем /^(Jos)+h$/ .

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

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

Они позволяют задавать наборы возможных значений для группы символов. Это выглядит следующим образом: (white|wheat) . В контексте нашего примера с бутербродом, будет принят один из вариантов - либо „white“, либо „wheat“.

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

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

Мы говорили о regex с /двумя слэшами/, верно? Мы знаем, что находится между ними, но что должно быть снаружи?

Неожиданный поворот: ничего!

…слева. Правая сторона, напротив, может содержать множество, множество всего полезного. Даже стыдно, что мы так долго не сказали об этом ни слова!
Модификаторы задают правила, по которым применяются регулярные выражения.

Вот список основных модификаторов (с Regex101.com):

Модификатор Название Описание
g global Все совпадения
m multi-line ^ и $ соответствуют началу и концу каждой строки
i insensitive Регистронезависимое сравнение
x extended Пробелы и текст после # игнорируются
X extra \ с произвольной буквой, не имеющей особого значения, возвращает ошибку
s single line Игнорирует символы новой строки
u unicode Строки-шаблоны обрабатываются как UTF-16
U ungreedy По умолчанию в regex используется «ленивая квантификация». Модификатор U делает квантификацию «жадной»
A anchored Шаблон форсируется к ^
J duplicate Разрешает дублирующиеся имена субпаттерннов

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

Предположим, Эли взбесилась настолько, что начала бомбить чат сообщениями с БуквАМи рАЗных РегИсТРОв. Это нас не страшит, потому что i уже здесь! Мы можем легко задать гневливое выражение „I hAate LiVing witH JOSH!!!“ паттерном /i ha+te living with josh!+/i . Теперь наши regex стали легче читаемы, а также намного более мощны и полезны. Замечательно!

Вы можете самостоятельно поиграть с разными модификаторами. На мой взгляд, в целом вам больше всего пригодится igm .

Что дальше?

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

Существует множество символов и их сочетаний, используемых в регулярных выражениях. Обычно вы будете натыкаться на них во время изучения Stack Overflow, но о значении некоторых можно догадаться и из предыдущих примеров (например, \n - символ перехода на новую строку). База заложена, но выучить предстоит еще очень многое.

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

После точки

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

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

Все изменилось, когда мне пришлось более плотно работать с Google Analytics и Google Tag Manager в Netpeak.

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

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

Что такое регулярные выражения

Регулярные выражения (regular expressions, RegExp) — наборы символов, применяемых для поиска текстовых строк, соответствующих требуемым условиям. Результат применения регулярного выражения — подмножество данных, отобранное согласно логике, заложенной в выражении. Регулярные выражения применяются в любых задачах по поиску в множестве данных, для которых нужно получать выжимку по определенным правилам.

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

Большинство символов в регулярных выражениях представляют сами себя, за исключением группы специальных символов « \ / ^ $ . | ? * + () { }». Если эти символы нужно представить в качестве символов текста, их следует экранировать обратной косой чертой «\».

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

  • «^» — каретка, циркумфлекс или просто галочка. Начало строки;
  • «$» — знак доллара. Конец строки;
  • «.» — точка. Любой символ;
  • «*» - знак умножения, звездочка. Любое количество предыдущих символов;
  • «+» - плюс. 1 или более предыдущих символов;
  • «?» - вопросительный знак. 0 или 1 предыдущих символов;
  • «()» - круглые скобки. Группировка конструкций;
  • «|» - вертикальная линия. Оператор «ИЛИ»;
  • «» - квадратные скобки. Любой из перечисленных символов, диапазон. Если первый символ в этой конструкции - «^», то массив работает наоборот - проверяемый символ не должен совпадать с тем, что перечислено в скобках;
  • «{ }» - фигурные скобки. Повторение символа несколько раз;
  • «\» - обратный слеш. Экранирование служебных символов.

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

  • \b — обозначает не символ, а границу между символами;
  • \d — цифровой символ;
  • \D — нецифровой символ;
  • \s — пробельный символ;
  • \S — непробельный символ;
  • \w — буквенный или цифровой символ или знак подчеркивания;
  • \W — любой символ, кроме буквенного или цифрового символа или знака подчеркивания.

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

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

1. Изучаем регулярные выражения в текстовом редакторе

  • в большинстве случаев спецсимволы не нужно экранировать;
  • Notepad++ сохраняет конструкции предыдущих запросов;

2. Проверяем знания регулярных выражений в Regex

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

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

    карова - очевидно, шаблон, под который подходит слово карова;

    \b(shift|unshift|pop|push|splice)\b - любое из перечисленных слов;

    ^\s+ - один или несколько пробелов или знаков табуляции, стоящих в начале строки.

В регулярных выражениях алфавитно-цифровые символы обычно обозначают сами себя. Например, шаблон Hello указывает искать символ H , за которым следует e , затем l и т. д.

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

Имеются и другие символы, которые в шаблонах получают особый смысл вместо того, чтобы обозначать самих себя. Такие символы называются метасимволами . Приведём несколько примеров метасимволов, не указывая пока их особый смысл (список не является исчерпывающим): \.-(){}?*+^$| .

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

Если нужно вставить в регулярное выражение метасимвол, лишив его особого смысла, его следует защитить (экранировать ), поставив перед ним бэкслэш. Например, знак плюса в регулярное выражение вставляется как \+ .

Шаблон обозначает один из символов, перечисленных в квадратных скобках. Если, к примеру, нас интересует слово Hello , неважно, с большой или маленькой буквы, шаблон будет таким: ello . Вот шаблон, обозначающий маленькую гласную букву английского алфавита: . Ещё один пример - символьный класс, состоящий из обеих квадратных скобок: [\[\]] .

Если символьный класс включает символы, идущие подряд в кодовой таблице, достаточно указать первый и последний символы, вставив между ними дефис. К примеру, класс, обозначающий любую десятичную цифру, можно задать как . Буква английского алфавита обозначается как (здесь мы полагаемся на тот факт, что в любой кодовой таблице заглавные и маленькие английские буквы идут непрерывными блоками в алфавитном порядке; однако блок маленьких букв не следует сразу за блоком заглавных).

Можно определить символьный класс, состоящий из всех символов за исключением перечисленных - так называемое отрицание символьного класса . Для этого сразу за открывающей квадратной скобкой перед перечислением вставляется знак циркумфлекса ^ . Любой символ, не являющийся цифрой, можно обозначить как [^0-9] .

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

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

Наиболее часто используемые анкеры - привязка к началу (^) и концу ($) строки. Привязка к началу строки должна помещаться в начале шаблона, а привязка к концу - в конце.

Например, к шаблону ^анти подходят такие слова русского языка, как антидот, антисемитизм или античастица. Без привязки также подошли бы строки, не начанающиеся с «анти-», но содержащие это буквосочетание внутри, например, меркантилизм. Для поиска слов, заканчивающихся на «-ться» нужен шаблон ться$ (мы уверены почти на 100%, что все такие слова - это возвратные глаголы в инфинитиве). Ничто не мешает применять в шаблоне обе эти привязки.

Другой полезный анкер - привязка к границе между словами \b . Он соответствует месту в строке, находящемуся между символами, один из которых принадлежит классу \w , а другой - \W (в любом порядке). Эта привязка может соответствовать также началу или концу строки (в этом случае считается, что срока как бы окружена воображаемыми символами из класса \W).

Если мы ищем фрагмент, который должен подойти под один из нескольких шаблонов, нужно перечислить эти шаблоны, разделив вертикальной чертой | . Например, понедельник|вторник|среда|четверг|пятница|суббота|воскресенье. Для того, чтобы сделать список альтернатив самостоятельной единицей и отделить от соседних, его нужно заключить в скобки. Например, шаблон Уважаем(ый|ая) означает строку Уважаем, за которой следует одна из строк ый или ая. Без скобок шаблон Уважаемый|ая обозначал бы одну из строк Уважаемый или ая. У скобок имеется важное побочное действие, о котором будет сказано в разделе «Группировка и захват» .

Для того, чтобы указать, сколько раз может повторяться шаблон, после него ставят так называемые квантификаторы (от латинского слова quantum - сколько):

Квантификаторы * , + и? являются избыточными, поскольку они могут быть выражены иначе с помощью фигурных скобок. А именно, * равносилен {0,} , + равносилен {1,} , а? - то же самое, что и {0,1} . Но данные квантификаторы очень часто используются, и этим заслужили отдельных обозначений.

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

Вот несколько примеров:

    ^\d+$ - последовательность из одной или нескольких десятичных цифр (шаблон для целых неотрицательных чисел в десятичной записи);

    ^\-?\d+$ - то же самое, но для всех (возможно, отрицательных) целых чисел;

    ^\-?(\d+(\.\d*)?|\.\d+)$ - шаблон для вещественных чисел;

Разберём последний пример подробнее. Помимо необязательного минуса в начале, в шаблоне присутствует группа с двумя альтернативами: \d+(\.\d*)? и \.\d+ . Первая альтернатива включает обязательную целую часть \d+ (как минимум одна цифра), и следующую за ней необязательную дробную (\.\d*)? . В дробной части, если она есть, имеется десятичная точка, и, возможно, несколько цифр. Таким образом, этой альтернативе соответствуют строки 15 , 15. , 15.487 . Другая альтернатива нужна для строк вида.618 с отсутствующей целой частью - во многих компьютерных языках эта запись имеет право на существование.

Если простейшие элементы регулярного выражения - символы, символьные классы и анкеры, записываются подряд, это означает, что при поиске в строке по шаблону эти элементы будут сопоставляться с частями строки последовательно, в той же последовательности. Этот порядок нарушается, если применяются альтернативы. Можно представлять себе, что составное регулярное выражение составляется из простейших при помощи двух операций: последовательного соединения (композиции ) и альтернативы. Композиция - аналог операции умножения в арифметике. Альтернатива - аналог сложения. Первое сходство с арифметикой состоит в том, что операция альтернативы имеет более низкий приоритет, чем композиция, поэтому могут потребоваться скобки для группировки, как в примере Уважаем(ый|ая) .

Примечание

Многие, хотя и не все, законы арифметики действуют и для регулярных выражений:

коммутативность альтернативы x | y = y | x ; ассоциативность альтернативы x | y | z = x | y | z ; ассоциативность композиции x ⁣ y ⁣ z = x ⁣ y ⁣ z ; дистрибутивность альтернативы относительно композиции (левая и правая) x ⁣ y | z = x ⁣ y | x ⁣ z , x | y ⁣ z = x ⁣ z | y ⁣ z .

В этой странной арифметике регулярных выражений не имеет место закон коммутативности для композиции. Кроме того, отсутствует аналог нуля из-за очевидного соотношения x | x = x . Роль единицы (правой и левой) для композиции выполняет пустой шаблон (обозначим его 𝟙): 𝟙 ⁣ x = x ⁣ 𝟙 = x . Квантификаторы вида { n } играют роль возведения в n -ю степень.

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

А, может быть, этилендиамин- N N N ′ N ′ -тетрауксусной кислоты?

Рассмотрим пример, в котором в тексте отыскиваются упоминания различных кислот. Наши школьные воспоминания из химии навели нас на мысль, что названия кислот оканчиваются или на вая, или на ная, или на тая, а затем, после пробела, следует слово кислота. Составляем шаблон: \S+[внт]ая кислота. Сопоставляем с шаблоном текст. Удача! Но, спрашивается, упоминание какой именно кислоты нашлось в тексте? Соляной? Серной? Азотной? Плавиковой? Хлорной? Хлорноватой? Хлорноватистой? Лимонной? Синильной? Дезоксирибонуклеиновой?

Вот здесь пригодится захват. Ту часть шаблона, который, по нашему замыслу, должен соответствовать названию, заключим в скобки: (\S+[внт]ая) кислота. Тогда машина, найдя в тексте упоминание кислоты, сохранит её название (то, что соответствует заключённому в скобки фрагменту шаблона) в специальной переменной - буфере захвата

Регулярное выражение может содержать несколько групп захвата. Такие группы могут не только следовать друг за другом, но и вкладываться одна в другую. Иными словами, регулярное выражение должно быть сбалансировано по отношению к круглым скобкам в том же смысле, какой обсуждался в главе 23. «Проверка баланса скобок » (конечно, это относится только к круглым скобкам, служащим цели группировки и захвата; скобки, которым предшествует бэкслэш, не сказываются на балансе групп). При успешном поиске каждая группа захватит какую-то часть текста: первая - в первый буфер, вторая - во второй, и так далее. Как же нумеруются группы в случае, когда они вложены друг в друга? Нумерация идёт в том порядке, в каком появляются открывающие скобки:

2 4 5 ┝┑ ┝┑┝┑ (()(()())) │ ┝━━━━┙│ │ 3 │ ┝━━━━━━━━┙ 1

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

Использование нумерованных групп захвата не всегда удобно, особенно в больших регулярных выражениях. Стоит только вставить в шаблон новую группу захвата, как нумерация сбивается. Тогда придётся во всех местах в программе, где происходит обращение к буферам захвата по номерам, вносить исправления. Но можно связать с группой имя, которое позволит обратиться к соответствующему буферу по этому имени. Для создания именованной группы используются ограничители (? ⋯) , где вместо name подставляется нужное имя.

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

Рассмотрим задачу поиска слов, содержащих три одинаковые гласных буквы подряд. Наивное решение [аеёиоуэюя]{3} , использующее квантификаторы, не будет работать, поскольку такому шаблону соответствуют строки с тремя подряд идущими гласными, но необязательно одинаковыми. Чудовищное решение с полным перечислением альтернатив, ааа|еее|ёёё|иии|ооо|ууу|эээ|ююю|яяя, мы с негодованием отвергаем: ведь стоит взять другой, более обширный символьный класс, или заменить тройку в квантификаторе на большее значение, как размер шаблона катастрофически вырастет.

Тем не менее возможно элегантное решение, использующее группы захвата. Захватим гласную в группу, а затем сошлёмся на содержимое буфера захвата. Ссылки на первый, второй, третий буферы записываются в регулярном выражении как \g1 , \g2 , \g3 . Итак, решением будет шаблон ([аеёиоуэюя])\g1{2} . Обратите внимание, что ссылка на буфер захвата должна следовать в регулярном выражении строго после соответствующей группы.

Обратные ссылки могут ссылаться не только на нумерованные буферы, но и на именованные. Такие ссылки имеют вид \k , где, опять же таки, вместо name стоит конкретное имя. Наш пример можно переписать, применяя именованные группы: (?[аеёиоуэюя])\k{2} (vowel - гласная).

Иногда возникает необходимость в поиске, при котором не делается отличий между строчными и прописными буквами. Такой поиск называется нечуствительным к регистру (case-insensitive ). Вместо того, чтобы всюду в шаблоне заменять буквы на двухбуквенные классы (a → , b → , …), Просто заключим шаблон в специальную группу, включающую режим case-insensitive поиска: (?i: ⋯) . Такая группа не является группой захвата. Если case-insensitive поиск должен быть реализован только в части регулярного выражения, в группу следует поместить только нужную часть.

Наоборот, если какая-то часть регулярного выражения, в которой осуществляется case-insensitive поиск, нуждается в отключении этого режина, то вернуться к обычному, case-sensitive поиску можно, используя группу (?-i: ⋯) .

Режимы чувствительности/нечуствительности к регистру влияют лишь на буквы. Что считается буквой, а что нет, зависит от языка, как и правила соответсвия между прописными и строчными буквами. С точки зрения английского языка, например, буквой не является символ Щ. В немецком языке имеется буква ß (между прочим, заглавный вариант этой буквы состоит из двух букв SS: Carl Friedrich Gauß → CARL FRIEDRICH GAUSS).

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

1. Введение

Пара слов для тех, кто не совсем в курсе, о чем идет речь. Вы видели когда-нибудь маски имен файлов — всякие там *.html, filename.{txt|csv} и тд? Так вот, регулярные выражения — это те же «маски», только более сложные. В умелых руках регулярные выражения могут быть невероятно мощным инструментом . Так или иначе они используются в 95% моих скриптов.

Многие небезосновательно считают, что регулярные выражения — это скорее самостоятельный язык программирования, чем часть какого-либо языка. Регулярные выражения есть в Perl, PHP, Python , JavaScript, конфигурационных файлах Apache… В зависимости от языка, могут иметь место небольшие различия в синтаксисе регулярных выражений, но основные идеи везде одни и те же.

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

if (preg_match ("//" , $text ) ) {
// в тексте есть цифры
} else {
// в тексте нет ни одной цифры
}

и такой — на Perl:

if ($text =~ // ) {
# в тексте есть цифры
} else {

}

делают одно и то же. Как не сложно догадаться по комментариям в коде, здесь идет проверка, содержит ли строка $text хотя бы одну цифру.

2. Простые примеры

Как всегда, учиться будем на примерах. Квадратные скобки в регулярных выражениях означают «здесь должен быть один из перечисленных символов». Например, приведенному выше выражению соответствует любая строка, содержащая хотя бы одну цифру. Аналогично, выражению соответствует любая строка, содержащая хотя бы одну из первых трех букв латинского алфавита. Чтобы обозначить любой символ, кроме заданных, используется запись [^abcdef] , то есть с символом крышки сразу за открывающейся квадратной скобкой.

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

if ($text =~ // ) {
# в тексте есть цифры
} else {
# в тексте нет ни одной цифры
}

И еще пара примеров:

if ($text =~ // ) {
# в тексте есть цифры и/или строчные буквы
# подходит: abc, ZZaZZ, ===17
# не подходит: EPIC FAIL, @^*!@#
}

if ($text =~ /[^0-9]/ ) {
# в тексте есть символы, отличные от цифр
# подходит: abc, 123abc456, 0x1111111111
# не подходит: 123, 123456, 9999999999
}

if ($text =~ // ) {
# в тексте есть буквы латинского алфавита
# подходит: ___Abba___, zyx
# не подходит: 0123, ^_^
}

if ($text =~ // ) {
# текст содержит цифры и буквы от A до F
# подходит: ***777***, DeadC0de, intel, 0_o
# не подходит: Xor, wiki
}

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

if ($text =~ /num=/ ) {
# подходит: num=1, some_num=000, bebenum=2(&^*
# не подходит: NUM=1, my_num=-1, num=abc
}

if ($text =~ // ) {
# подходит:
# zzzzzz
#
# не подходит:
#
#
}

Внимательный читатель поинтересуется, что это за знак плюса стоит в последнем регулярном выражении? Этот символ означает «один или более символов, указанных перед этим плюсом». Почти то же самое обозначает символ звездочка «от нуля до сколько угодно символов, указанных перед звездочкой». Например, выражению A+ будет соответствовать последовательность из одного и более символов A, а выражению * — любое количество цифр, в том числе и ни одной.

Иногда количество символов нужно задать точнее. Это можно сделать с помощью фигурных скобок . Например, выражению {8} соответствует любая последовательность из ровно восьми цифр, а выражению {3,8} — последовательность, содержащая от 3-х до 8-и символов латинского алфавита.

Число на второй позиции можно не указывать. То есть выражение {3,} также может иметь место. Оно означает «не менее трех строчных букв латинского алфавита». Выражение {0,} полностью аналогично звездочке, а {1,} — плюсу. Выражение {0,1} можно записать более коротко, используя знак вопроса .

Пример (не самый простой, зато интересный):

if ($text =~ // ) {
# подходит:
# dfgddfgdfg
#
# не подходит:
#
#
}

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

3. Как выдрать кусок строки?

Символ вертикальной черты (он же «пайп» или просто «палка») в регулярных выражениях означает «или». Например, выражению {20}|{25} соответствуют все строки, содержащие 20 символов латинского алфавита или 25 цифр подряд. Обычно этот символ используется совместно с круглыми скобками , предназначенных для группировки частей регулярного выражения. Пример:

if ($filename =~ /backup(19|20){2}-{2}-{2}/ ) {
# подходит: backup2011-04-01, backup1999-01-13
# не подходит: backup1873-12-12, backup2101-07-07
}

У круглых скобок есть еще одна функция. С их помощью можно выдирать куски соответствующих строк. В PHP результат сохраняется в переменную, указанную третьим аргументом функции preg_match . В Perl совпадения для 1-ой, 2-ой … 9-ой пары скобок сохраняются в переменные $1, $2, …, $9 . Но удобнее использовать такую конструкцию:

if (my ($y , $m , $d ) =
$filename =~ /backup({4})-({2})-({2})/ ) {
print ;
}

Спрашивается, под каким номером искать совпадение в возвращаемом массиве, если регулярное выражение содержит вложенные скобки? Все просто — совпадения возвращаются в том же порядке, в котором идут открывающиеся скобки. Пример:

my $filename = "./dumps/backup2011-04-01.tgz" ;
$filename =~ /backup((20|19){2})-({2})-({2})/ ;
print "$1, $2, $3, $4\n " ;
# выведет: 2011, 20, 04, 01

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

if (my ($y , $m , $d ) =
$filename =~ /backup((?:20|19){2})-({2})-({2})/ ) {
print "year = $y, month = $m, day = $d\n " ;
}

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

4. Начало и конец строки

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

if ($text =~ /^*/ ) {
# текст, начинающийся с десятичной цифры
# подходит: 3, 801403, 6543bebebe
# не подходит: 0275, -123, abc11111
}

if ($text =~ /^0x{1,8}$/ ) {
# шестнадцатеричное число в C-нотации
# подходит: 0x5f3759df, 0xDEADBEEF
# не подходит: 0x1234xxx, xxx0x5678, xxx0x9ABCxxx
}

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

Примечание: Если кого-нибудь интересует, что это за «магические числа» 0x5f3759df и 0xDEADBEEF , обращайтесь к Википедии.

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

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

if (my ($name ) = $arg =~ /^--name=(.+)$/ ) {
print "Hello, $name!\n " ;
}

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

<span > Text <em > text</ em > text</ span > Source: http://сайт/</ span >

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

# в регулярном выражении содержится слэш, поэтому
# приходится использовать вместо него другой ограничитель
(.*)#;
print $text ;
# выведет наиболее длинное совпадение:
# Text text textSource: http://сайт/

А вот что произойдет, если отключить жадный разбор (внимание на знак вопроса):

my ($text ) = $data =~ m #(.*?)#;
print $text ;
# выведет первое совпадение:
# Text text text

Да, следующие строки делают одно и то же:

# обычная запись...
$text =~ /({4})-({2})-({2})/ ;
# на самом деле - лишь сокращение оператора m//
$text =~ m/({4})-({2})-({2})/ ;
# вместо слэша можно использовать разные скобочки:
$text =~ m { ([ 0 - 9 ] { 4 } ) - ([ 0 - 9 ] { 2 } ) - ([ 0 - 9 ] { 2 } ) } ;
$text =~ m< ([ 0 - 9 ] { 4 } ) - ([ 0 - 9 ] { 2 } ) - ([ 0 - 9 ] { 2 } ) >;
$text =~ m [ ([ 0 - 9 ] { 4 } ) - ([ 0 - 9 ] { 2 } ) - ([ 0 - 9 ] { 2 } ) ] ;
$text =~ m (([ 0 - 9 ] { 4 } ) - ([ 0 - 9 ] { 2 } ) - ([ 0 - 9 ] { 2 } ) ) ;
# или даже такие символы:
$text =~ m ! ([ 0 - 9 ] { 4 } ) - ([ 0 - 9 ] { 2 } ) - ([ 0 - 9 ] { 2 } ) !;
$text =~ m | ([ 0 - 9 ] { 4 } ) - ([ 0 - 9 ] { 2 } ) - ([ 0 - 9 ] { 2 } ) |;
$text =~ m #({4})-({2})-({2})#;
# а также крышку, кавычки, двоеточие, запятую, точку, ...

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

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

# экранированная обратным слэшем точка
# означает именно точку, а не "любой символ"
my ($ext ) = $fname =~ /\.(+)$/ ;
print "file name: $fname, extension: $ext\n " ;

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

  • \t — обозначает символ табуляции (t ab)
  • \r и \n — символы возврата каретки (r eturn) и новой строки (n ew line)
  • \xNN — соответствует символу с ASCII кодом NN, например \x41 соответствует заглавной букве A латинского алфавита
  • \s — соответствует пробелу (s pace), табуляции, символу новой строки или символу возврата каретки
  • \d — означает любую цифру (d igit), а точнее — то, что считается цифрой в Юникоде (см слайд номер 102 в этой презентации)
  • \w — означает так называемое «слово» (w ord), аналог

В последних трех выражениях запись буквы в верхнем регистре означает отрицание. Например, \D соответствует выражению [^0-9] , \W — выражению [^0-9a-zA-Z_] , а \S — любому «не пробельному» символу.

Все эти «буквенные» выражения можно использовать внутри квадратных скобок. Например, выражение полностью эквивалентно .

Особого внимания заслуживают выражения \b и \B , означающие границу слова (в том же понимании «слова», как и в случае с \w ) и отсутствие границы слова соответственно. Например, выражению perl\b соответствует строка «perl rulez!», но не соответствует «perlmonk». С выражением perl\B все с точностью наоборот. Надеюсь, идея ясна.

И еще один пример:

# разбиваем полное имя файла на путь и имя
my ($path , $fname ) = $full_name =~ /^(.*)\/([^\/]+)$/ ;

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

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

Поведение регулярных выражений можно менять с помощью модификаторов. Например, как вы уже могли заметить, соответствие строки регулярному выражению проверяется с учетом регистра символов. Изменить это поведение можно с помощью модификатора #(.*?)#g;
# будьте осторожны при использовании /g в скалярном контексте
# подробности здесь: http://koorchik.blogspot.com/2011/07/perl-5.html
print "$_\n " for (@words ) ;

Как было сказано выше, точка обозначает любой символ, кроме символа новой строки . Изменить такое поведение можно с помощью модификатора /s :

# выдираем из HTML-файла содержимое статьи,
# которое может содержать далеко не одну и не две строчки
my ($article ) = $html =~ m #

(.*?)
#s;

Кстати, если в регулярном выражении нужно обозначить «любой символ» без использования модификатора /s , используйте выражение [\d\D] . Оно означает «любой символ, являющийся цифрой, или не являющийся цифрой», то есть вообще любой символ.

Наконец, ничто не мешает использовать несколько модификаторов одновременно:

# выдираем из HTML-файла все, что выделено жирным
my @words = $html =~ m #(.*?)#gi;
# сработает для , или даже

Дополнение: Еще один полезный модификатор — /o . Он означает «компилировать регулярное выражение только один раз». В некоторых случаях этот модификатор может существенно ускорить скрипт. Правда, я не уверен, что он поддерживается где-то, кроме как в Perl. За наводку спасибо товарищу

Шпаргалка представляет собой общее руководство по шаблонам регулярных выражений без учета специфики какого-либо языка. Она представлена в виде таблицы, помещающейся на одном печатном листе формата 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}

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