Каталог статей
Поиск по базе статей  
Статья на тему Интернет » Интересное в сети » Perl: найти и&nb p;не сдаваться

 

Perl: найти и&nb p;не сдаваться

 

 

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

загрузка...

 

 

Меняем формат даты

Проблема: в тексте встречаются даты, записанные в формате ГГГГ-ММ-ДД, например, 2004-09-30. Требуется изменить формат записи на более привычный русскоязычному пользователю ДД.ММ.ГГГГ. То есть дата должна выглядеть так: 30.09.2004.

Метасимвол \d соответствует цифрам, метасимвол-повторитель {n} обозначает количество повторений предыдущего символаСинтаксис операций замены по шаблону или, иными словами, операций подстановки, в языке Perl выглядит следующим образом: s/что меняем/на что меняем/. Какие же фрагменты текста мы должны найти, чтобы изменить? Эти фрагменты выглядят следующим образом: четыре цифры — две цифры — две цифры. Как их записать в формате регулярных выражений Perl? Например, так: (\d{4})-(\d{2})-(\d{2}).

Обратите внимание на круглые скобки. Они не только разбивают регулярное выражение на некие фрагменты, но и заставляют Perl присваивать значения этих фрагментов переменным вида $n, где n — положительное число. В нашем случае переменной $1 будет присвоено значение \d{4}, то есть, год, переменной $2\d{2} (месяц), переменной $3\d{2} (день). Зная об этом, мы сможем записать вторую часть подстановки, то есть на что меняем.

Обратный слеш \ заставляет воспринимать следующую за ним точку именно как точку, а не как метасимвол подстановки любого символаВыглядеть эта часть будет так: $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, а затем применяется составленное нами выражение подстановки. Таким образом, в новую переменную записывается тот же текст, но дата в нем меняет свой формат. В седьмой строке мы слегка изменяем текст «на выходе». Для этого опять-таки применяется операция подстановки: с помощью метасимвола \D+ мы находим все нечисловые символы в тексте, от его начала до первой встречающейся цифры, и заменяем их на другой текст. Кстати, попробуйте удалить метасимвол-повторитель + и взгляните, как изменится результат работы скрипта.

Препарируем путь к файлу

Проблема: известен полный путь к файлу, например, c:/temp/somefile.txt. Необходимо выделить в нем все составляющие части (имя диска, каталог, имя файла и его расширение), а затем сменить имя диска: j:/temp/somefile.txt.

Эта задача довольно проста. В общем случае путь к файлу выглядит следующим образом:

  1. латинская буква, соответствующая имени диска, и двоеточие после нее,
  2. имена каталогов, в которых расположен файл, ограниченные символом слеша / с обеих сторон,
  3. имя файла,
  4. расширение файла.

Запишем эти составные части в синтаксисе регулярных выражений: ([a-z]:)(.*\/)(.*)(\..*). Здесь:

  1. [a-z]: — обозначает одну любую букву латинского алфавита и двоеточие после нее,
  2. .*\/ — обозначает любое количество символов, включая последний слеш в пути к файлу,
  3. .* — обозначает любое количество символов,
  4. \..* — обозначает любое количество символов от последней точки в пути к файлу.

Операция поиска по шаблону в общем случае записывается очень просто: =~ /шаблон/Теперь нам достаточно проверить имеющееся значение переменной на соответствие данному шаблону. Для этого необязательно использовать подстановку, ограничимся простой операцией поиска по шаблону. Причем, как мы помним, значения всех фрагментов регулярного выражения, помещенных в круглые скобки, Perl будет автоматически присваивать переменным $1, $2 и так далее. Отсюда выводим простенькую функцию:

 $file_path_and_name = "c:/temp/somefile.txt";
# Проверяем соответствие значения переменной
# составленному нами шаблону.
# в случае успеха переменным $n присваиваются некоторые значения:
if ($file_path_and_name =~ /([a-z]:)(.*\/)(.*)(\..*)/ ) {
# Если условие выполнено, выводим на экран необходимые значения:
print "Файл расположен на диске <b>$1</b><br>
Файл расположен в каталоге <b>$1$2</b><br>
Имя файла: <b>$3</b><br>
Расширение файла: <b>$4</b><br>";
# Делаем подстановку для изменения имени диска:
($new_disc = $file_path_and_name) =~ s/[a-z]/j/;
print "<hrgt;В результате подстановки файл \"лег\" на другой диск: <b>$new_disc</b>";
}
# Если значение переменной не соответствует шаблону,
будет выведено предупреждение:
else {
print "Внимание! Значение переменной не соответствует шаблону пути к файлу!";
}

Обратите внимание на сделанную нами подстановку. В результате этой подстановки первая латинская буква, встреченная в пути файла, будет заменена на j. Здесь важно понимать: для того чтобы скрипт отработал нормально, данная подстановка должна быть включена в тело оператора if. Зачем? Для дополнительной подстраховки. Вдруг в переменной по каким-то причинам первой стоит не латинская буква, а знак препинания или буква из другого алфавита? Например: я:/temp/somefile.txt. В этом случае подстановка найдет первый символ, соответствующий условию [a-z] (в нашем примере это t) и заменит его на букву j: я:/jemp/somefile.txt. Если же мы включим операцию подстановки в тело оператора if, то любое несоответствие шаблону приведет к выводу на экран предупреждающего сообщения, описанного в теле оператора else, а неправильных подстановок не произойдет.

Простая транслитерация

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

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

  • В обоих списках транслитерации можно использовать одиночные символы или диапазоны (перечни) вроде [a-z], [а-я], [0-9] и т.д. Например, tr/[A-Z]/[a-z]/ обозначает замену букв верхнего регистра на соответствующие буквы нижнего.
  • Порядок следования символов и диапазонов в списках замены должен совпадать. Скажем, если длинное тире в первом списке стоит на пятой позиции, то во втором списке дефис так же должен стоять на пятой позиции.
  • В отдельных случаях можно использовать в списках замены непосредственно одиночные символы, например, тот же дефис. Но для пущей корректности правильно использовать коды, например, метасимволы вида \xDD, где DD — шестнадцатеричный код символа (см. предыдущую публикацию на тему регулярных выражений).

Для демонстрации одного из решений описанной выше задачи предлагаем воспользоваться такой функцией:

 $old_text = "«Привет!» — сказала Матрёна.";
print "До транслитерации: <b>$old_text</b><br>";
($new_text = $old_text) =~ tr/\xAB\xBB\x97\xB8/\x22\x22\x2D\xE5/;
print "После транслитерации: <b>$new_text</b>";

Здесь в списки транслитерации подставлены следующие шестнадцатеричные коды:

  • xAB — открывающие типографские кавычки,
  • xBB — закрывающие типографские кавычки,
  • x97 — длинное тире,
  • xB8 — буква ё,
  • x22 — обычные кавычки,
  • x2D — дефис,
  • xE5 — кириллическая буква е,

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

Ссылки по теме




Статья получена: hostinfo.ru
загрузка...

 

 

Наверх


Постоянная ссылка на статью "Perl: найти и&nb p;не сдаваться":


Рассказать другу

Оценка: 4.0 (голосов: 16)

Ваша оценка:

Ваш комментарий

Имя:
Сообщение:
Защитный код: включите графику
 
 



Поиск по базе статей:





Темы статей






Новые статьи

Противовирусные препараты: за и против Добро пожаловать в Армению. Знакомство с Арменией Крыша из сэндвич панелей для индивидуального строительства Возможно ли отменить договор купли-продажи квартиры, если он был уже подписан Как выбрать блеск для губ Чего боятся мужчины Как побороть страх перед неизвестностью Газон на участке своими руками Как правильно стирать шторы Как просто бросить курить

Вместе с этой статьей обычно читают:

Как найти хулигана, испортившего машину

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

» Разное - 8615 - читать


ИРКа поможет найти инвесторов IT-стартапу

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

» Продвижение и оптимизация - 2515 - читать


Ссылочный спам: найти и обезвредить

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

» Продвижение и оптимизация - 2966 - читать


Perl: бороться и&nb p;искать

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

» Интересное в сети - 1354 - читать


Perl: жадный и&nb p;торопливый возвращенец

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

» Интересное в сети - 1333 - читать



Статья на тему Интернет » Интересное в сети » Perl: найти и&nb p;не сдаваться

Все статьи | Разделы | Поиск | Добавить статью | Контакты

© Art.Thelib.Ru, 2006-2024, при копировании материалов, прямая индексируемая ссылка на сайт обязательна.

Энциклопедия Art.Thelib.Ru