Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 [ 70 ] 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242

6.20. Поиск сокращений 227

делить, какое действие выбрал пользователь, с помощью конструкции $answer= =~ /"AB0RT/1. Выражение будет истинным, если $answer начинается со строки "ABORT". Однако совпадение произойдет и в случае, если после "ABORT" в Sanswer следует что-то еще - скажем, для строки "ABORT LATER". Обработка сокращений обычно выглядит весьма уродливо: $answer =~ /ACBCOCRCT))?))?$/!.

Сравните классическую конструкцию переменная =~ шаблон" с "ABORT" = / "\Q$answer/i. \Q подавляет интерпретацию метасимволов, чтобы ваща программа не «рухнула» при вводе пользователем неверного шаблона. Когда пользователь вводит что-нибудь типа "аЬ", после замены переменной шаблон принимает вид "ABORT" =~ /"ab/i. Происходит совпадение.

Стандартный модуль Text::Abbrev работает иначе. Вы передаете ему список слов и получаете ссылку на хэш, ключи которого представляют собой все однозначные сокращения, а значения - полные строки. Если ссылка Shref создается так, как показано в решении, $href->{$var} возвращает строку "abort".

Подобная методика часто используется для вызова функции по имени, вводимому пользователем. При этом применяется символическая ссылка;

$name = "send"; &$name();

Впрочем, это небезопасно - пользователь сможет выполнить любую функцию нашей программы, если он знает ее имя. Кроме того, такое решение противоречит директиве use strict "refs".

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

# Предполагается, что &invoke editor, &deliver message,

й Sfile и SPACER определяются в другом месте.

use Text Abbrev,

my(Shref, %actions, Serrors);

%actions = (

"edit"" => \&invoke editor,

"send" => \&deliver message.

""list" => sub { system(SPACER, Sfile) },

""abort" => sub {

print ""See ya\n""; exit;

=> sub {

print "Unknown command Scmd\n"", Serrors++;

Shref = abbrev(keys %actions), local S ;

for (print "Action ""; <>; print ""Action: ") < s/-\s+ . s/\s+S ;



> Смотри также-

Документация по стандартному модулю Text::Abbrev. Интерполяция рассматривается в разделе Scalar Value Constructors* perldata(l).

6.21. Программа: urlify

Программа urlify оформляет URL-адреса, найденные в файлах, в виде ссылок HTML. Она работает не для всех возможных URL, но справляется с наиболее распространенными. Программа старается избежать включения знаков препинания, завершающих предложения, в помеченный URL.

Профамма является типичным фильтром Perl и потому может использоваться для перенаправленного ввода:

% gunzip -с ~/mail/archive.gz urlify > archive.urlifled

Исходный текст программы приведен в примере 6.13.

Пример 6.13. urlify

й!/usr/bin/perl

# urlify - оформление URL-подобных конструкций в виде ссылок HTML

Surls = (httpltelnetlgopherlfilelwaislftp);

Sltrs = AW;

Sgunk = 7«-:.?+=8,Ч@!\-;

Spunc = .:?\-;

$any = •${ltrs}${gunk}${punc}";

while (<>) { s{

\b # Начать с границы слова

( и Начать сохранение $1 {

Surls : Я Искать имя ресурса и двоеточие,

[Sany] +? # эа которыми следует один или более

й любых допустимых символов, но

# проявлять умеренность и брать лишь то,

# что действительно необходимо .,,. ) й Завершить сохранение $1 }

next unless $ ;

$actions->{ $href->{ lc($ ) } }->();

Если вы не любите слишком кратких выражений или хотите приобрести навыки машинистки, последнюю команду можно записать так:

Sabbreviation = 1с($ );

Sexpansion = $href->{$abbreviation};

Scoderef = $actions->{$expansion};

&$coderef();



6.22. Программа: tcgrep

Ниже приведена программа UNIX grep, написанная на Perl. Хотя она работает медленнее версий, написанных на С (особенно GNU-версии grep), зато обладает многими усовершенствованиями.

Первая и самая важная особенность - эта программа работает везде, где работает Perl. Имеется ряд дополнительных возможностей - tcgrep игнорирует все файлы, кроме простых текстовых; распаковывает сжатые или обработанные утилитой gzip файлы; выполняет просмотр в подкаталогах; ищет полные абзацы или записи, определенные пользователем; ищет более свежие версии файлов, а также подчеркивает или выделяет найденные совпадения. Кроме того, параметр -с выводит количество найденных записей, а параметр -С - число найденных совпадений, которые могут содержать несколько записей.

Распаковка сжатых файлов выполняется утилитами gzcat или zcat, поэтому данная возможность отсутствует в системах, где эти программы недоступны, а также в системах, не позволяющих запускать внешние программы (например, Macintosh).

При запуске программы без аргументов на экран выводится краткая справка по ее использованию (см. процедуру usage в программе). Следующая командная строка рекурсивно и без учета регистра ищет во всех файлах почтового ящика -/mail сообщения с отправителем "kate" и выводит имена найденных файлов:

% tcgrep -ril "From: .kate ~/mail

Исходный текст программы приведен в примере 6.14.

Пример 6.14, tcgrep

й!/usr/bin/perl -w

й tcgrep: версия grep, написанная на Perl

# версия 1.0

# версия 1,1

# версия 1.2

# версия 1,3 й версия 1.4

use strict;

30 сентября 1993 года 1 октября 1993 года 26 июля 1996 года 30 августа 1997 года 18 мая 1998 года

й Глобальные переменные

(?= # Опережающая проверка без смещения

[Spunc]* # либо О, либо знак препинания,

["$апу] й за которыми следует символ, не входящий в url,

I # или

$ # конец строки

}{<А HREF="$r>$1</A>}igox; print;



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 [ 70 ] 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242