[использование регулярных выражений Perl для подстановки и транслитерации]материал подготовил: Александр Якутский 09.09.2004
В одной из прошлых публикаций мы начали разговор о регулярных выражениях языка Perl, а точнее, о том, как с помощью этих выражений составляются шаблоны для поиска различных данных. Однако зачастую одним только поиском задача не исчерпывается. Как правило, возникает необходимость совершить некое действие над найденным фрагментом данных. В этой статье мы рассмотрим варианты решения нескольких задач такого типа. Предполагается, что читатель внимательно ознакомился с предыдущей публикацией, что он знаком с азами записи и исполнения Perl-скриптов, протестирует приведенные здесь примеры решения задач, поэкспериментирует с заменой метасимволов и так далее.
Меняем формат даты
Проблема: в тексте встречаются даты, записанные в формате ГГГГ-ММ-ДД, например, 2004-09-30. Требуется изменить формат записи на более привычный русскоязычному пользователю ДД.ММ.ГГГГ. То есть дата должна выглядеть так: 30.09.2004.
Синтаксис операций замены по шаблону или, иными словами, операций подстановки, в языке Perl выглядит следующим образом: s/что меняем/на что меняем/. Какие же фрагменты текста мы должны найти, чтобы изменить? Эти фрагменты выглядят следующим образом: четыре цифры — две цифры — две цифры. Как их записать в формате регулярных выражений Perl? Например, так: (\d{4})-(\d{2})-(\d{2}).
Обратите внимание на круглые скобки. Они не только разбивают регулярное выражение на некие фрагменты, но и заставляют Perl присваивать значения этих фрагментов переменным вида $n, где n — положительное число. В нашем случае переменной $1 будет присвоено значение \d{4}, то есть, год, переменной $2 — \d{2} (месяц), переменной $3 — \d{2} (день). Зная об этом, мы сможем записать вторую часть подстановки, то есть на что меняем.
Метасимвол \d соответствует цифрам, метасимвол-повторитель {n} обозначает количество повторений предыдущего символа
Выглядеть эта часть будет так: $3\.$2\.$1. Целиком выражение подстановки запишется следующим образом: s/(\d{4})-(\d{2})-(\d{2})/$3\.$2\.$1/. Как это выражение можно использовать на практике? Предлагаю скопировать и выполнить в браузере следующий небольшой скрипт:
#!/usr/bin/perl print "Content-Type: text/html\n\n"; # 1-я строка print "<html>"; # 2 $old_date = "2004-09-30"; # 3 $text_in = "Допустим, в некотором тексте встречается дата <b>$old_date</b>."; # 4 print "$text_in<br>"; # 5 ($text_out = $text_in) =~ s/(\d{4})-(\d{2})-(\d{2})/$3\.$2\.$1/; # 6 $text_out =~ s/\D+/В результате применения поиска и замены по шаблону формат даты изменился: <b>/; # 7 print "$text_out</b><br>"; # 8 print "<hr>Обратите внимание, что первоначальный текст не изменился:<br> <i>$text_in</i><br> Это и понятно, ведь в шестой строке скрипта мы обрабатывали не саму переменную <b>\$text_in</b>, а только ее копию."; # 9
Обратный слеш \ заставляет воспринимать следующую за ним точку именно как точку, а не как метасимвол подстановки любого символа
Что происходит при исполнении этого скрипта? В четвертой строке создается определенный текст (переменная $text_in), содержащий дату в «неправильном» формате. В шестой строке создается переменная $text_out, в которую копируется значение переменной $text_in, а затем применяется составленное нами выражение подстановки. Таким