Регулярные выражения (PHP, JavaScript, Perl)

Регулярные выражения (PHP, JavaScript, Perl)

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

Общие сведения

Регуля́рные выраже́ния (англ. regular expressions, жарг. регэ́кспы или ре́гексы) — современная система поиска текстовых фрагментов в электронных документах, основанная на специальной системе записи образцов для поиска. Образец (англ. pattern), задающий правило поиска, по-русски также иногда называют «шаблоном», «маской». Регулярные выражения произвели прорыв в электронной обработке текста в конце XX века.
Сейчас регулярные выражения используются многими текстовыми редакторами и утилитами для поиска и изменения текста на основе выбранных правил. Многие языки программирования уже поддерживают регулярные выражения для работы со строками. Например, Perl и Tcl имеют встроенный в их синтаксис механизм обработки регулярных выражений. Набор утилит (включая редактор sed и фильтр grep), поставляемых в дистрибутивах Unix, одним из первых способствовал популяризации понятия регулярных выражений.
Далее на Ру.Википедия

Каждый веб-программист сталкивался с задачей, когда в произвольном тексте нужно найти какие-то данные по какому-то закону, проверить данные, которые поступили от пользователя, подвергнуть найденные данные сложной модификации. Можно изобретать велосипед, а можно использовать средства, которые используют программисты всего мира. Иной раз кажется, что профи пользуются какими-то инструментами, приемами, которые доступны только им. Разочарую читателя, что профи используют те же средства и инструменты, что и вы, только разница состоит в том, что они ими умеют пользоваться и умеют выбирать, какой инструмент стоит использовать в конкретном случае.
Далее на PHPClub

А чтобы вам было интереснее, попробуйте получить имя файла, его расширение и букву диска из строки вида «E:KladovkaSoftDVDmakerreadme.txt» т.е.
E:
readme
txt

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

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

Применяются три основных отператора:
m/…/gimsxo — проверка совпадений (matching),
s/…/…/egimsxo — подстановка текста (substitution),
tr/…/…/ — замена текста (translation).
Вместо / можно ставить практически любой символ не находится в противоречиии с выражением (кроме ? и )

У этих трех операторов есть дополнительные параметры, но их расшировку я не привожу

Применение:
$t=»Мама мыла раму»;
$t =~ m/мама/бабушка/;

В результате получим: бабушка мыла раму

Кроме такой грубой замены можно использовать гораздо более тонкие механизмы.
Тут понадобятся метасимволы, которые имеют специальные значения:
^ — начало строки
$ — конец строки
( ) — объединение части шаблона в группу для последующего к ней обращения
— отмена специального значения следующего смвола
| — альтернатива (или)
[ ] — класс символов
. — одил любой символ, кроме начала строки

Модификаторы:
{n,m} — от n до m повторений предыдущего символа
? — 0 или 1 повторение предыдущего символа
+ — 1 или более повторений предыдущего символа
* — 0 или более повторений.

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

А теперь решение примера из первого блока:
$t=»E:KladovkaSoftDVDmakerreadme.txt»;
$t=~/^([^\]*)\(.*)(?=\)\(.*)(?=.).(…)/;
print «$1n»;
print «$2n»;
print «$3n»;
print «$4nn»;

Разбор примера «по скобкам». Т.к. эта группировка символов выбрана не случайно.
^ — разбор с начала строки. Мы подразумеваем, что у нас кроме этого пути в строке ничего нет.
([^\]*) — тут у нас все символы с начала строки, которые не совпадают с символом . На исключение указывает запись вида [^…]. Поставлены два символа , чтобы отменить его специальное значение. Несмотря на жадность * — остается вхождение до первого символа .
В первых круглых скобках у нас окажется E:
\ — показываем, что после E: у нас стоит обратный слэш ()
(.*)(?=\) — рассматриваем в совокупности. (.*) любая последовательность символов, за которой находится символ обратного слэша —> (?=\). Это, так называемое использование шаблона с «заглядыванием вперед». Причем учитывается именно последний обратный слэш. Во вторых скобках у нас KladovkaSoftDVDmaker
(.*)(?=.) — аналогичго предыдущему, но вместо слэша точка, чтобы отделить имя от расширения. В третьих скобках у нас: readme
(…) — группируем 3 последних символа. Получается: txt
$ — конец строки

А теперь выводим с помощью специальных переменных:
$1 для первой скобки, $2 для второй и т.д.
Конструкции со скобками вида (?…) - в специальные переменные не помещаются.

Регулярные выражения в Perl (ссылки)

Ссылки

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

Начну с того, что php поддерживает два стандарта регулярных выражений:
POSIX (http://www.php.net/manual/ref.regex.php)
PCRE — начиная с четвертой версии, совместимые с Perl (http://www.php.net/manual/ref.pcre.php).
Первый стандарт используется и сервером Apache в mod_rewrite а так же… MySQL в своих запросах (поищите слово «REGEXP» в руководстве по mysql, может сразу поймете, а я об этом позже расскажу). Второй, как ясно из названия, используется в системе perl. Два этих стандарта различаются несильно — во втором есть специальные символы, заменяющие наиболее часто используемые классы символов (например, цифры — d, а буквы и цифры — w) и специальные параметры шаблонов, позволяющие определять регистрозависимость поиска, привязку к концам строк и т.д (в функциях стандарта POSIX регистрозависимость реализована просто: есть функции ereg и ereg_eeplace, есть eregi (insensitive) и eregi_replace). В остальном же оба стандарта совместимы, а приемы написания шаблонов одинаковые.
Дальше на Оpennet.ru

Регулярные выражения в JavaScript (ссылки)

Ссылки

В силу того, что в JS я не работал c REGEX, то привожу только ссылки. По идее, значительных отличий нет. PCRE должен работать и тут =)

От автора

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

Вопросы и замечания по внутренней почте.