Стив Холзнер
От редактора: Когда мы публиковали это произведение, нам ничего не было известно об его авторстве. Спасибо нашим читателям, благодаря им мы нашли фамилию автора оригинального текста (Стив Холзнер). Но по-прежнему остается неизвестным герой, который перевел его на русский язык. Если Вам известно что-нибудь именно об этом переводе (существуют другие), пожалуйста, Этот e-mail адрес защищен от спам-ботов, для его просмотра у Вас должен быть включен Javascript ! Сам же текст прислан Тихоном Тарнавским aka t.t.
Алексей Федорчук
Определения
Регулярные выражения в perl одна из самых мощных его возможностей. Они позволяют сопоставлять текст с указанным шаблоном, разбивать текст в массив по шаблону, производить замену текста по шаблону и многое многое другое. Так-же иногда регекспами называются операторы поиска и замены.
Оператор q(text) заменяет строку text на строку, заключенную в одинарные кавычки(например если в q(text) поставить символ q(textn), то напечатает textn , т.е. n это два символа, подобно print ‘amam $file’ напечатает amam $file). В данном случае почти все специальные символы не будут интерпретироваться внутри q(), исключая »
$some=q(Don’t may be);
Оператор qq~text~; (вместо значка ~ можно ставить например знак |) позволяет работать со строками и многострочными текстами. пользуясь этим оператором можно выводить целые куски html-кода и писать в этом коде имена скалярных переменных.
Оператор qw(«text») разбивает строку на массив слов.
@mass=qw(«я вышел погулять и увидел как через реку строят новый мост»); #хотя с настроенной локалью будет работать и @mass=qw(я вышел погулять и увидел как через реку строят новый мост); for(@mass){print $_,»n»}
Оператор qr/pattern/ ключи — imosx работает подобно регулярному выражению s/…/…/
$rex=qr/my.STRING/is; s#$rex#foo#; #тоже самое, что и s/my.STRING/foo/is; Результат может использоваться подобно вызову подпрограммы(см perldoc perlop Regex quote like operator) $re=qr/$pattern/; $string=~/foo${re}bar/; $string=~$re; $string=~/$re/; Ключи imosx стандартные(см. ниже)
Оператор qx/STRING/ работает как системная команда, подобно $output = `cmd 2>$1`;. Программа, иллюстрирующая использование данного оператора:
#!/usr/bin/perl qx[dbfdump —fs=»x18″ —rs=»x19″ pdffile.dbf >pdffile.txt];
файл pdffile.dbf содержит memo-поля(memo-поле содержит ссылку, подобно функции seek, на текст в файле с расширением *.fpt), которые при помощи DBI.pm мне когда-то давно выудить не удалось. Принимает разрешения FoxBASE4 и дампит файлы со встроенными memo-полями в текстовый вид. Т.е. таким образом получилось вытащить информацию из файла memo-типа *.fpt.
Допустим используя команду $perl_info = qx(ps $$); мы выводим информацию о текущем процессе запущенного скрипта(каждая запущенная программа в UNIX имеет свой собственный уникальный идентификатор, который содержится во встроенной переменной $$ — достаточно уникальное число, можно использовать почти как счетчик случайных чисел). Если сказать $shell_info = qx’ps $$’; то выведет информацию о самом ps. Т.е. скобки осуществляют своеобразное экранирование от двойной кавычки.
В перл есть три основных оператора, работающих со строками:
m/…/ — проверка совпадений (matching),
s/…/…/ — подстановка текста (substitution),
tr/…/ — замена текста (translation).
Опертаор m/…/ анализирует входной текст и ищет в нем подстроку совпадающую с указанным шаблоном (он задан регулярным выражением). Оператор s/…/…/ выполняет подстановку одних текстовых фрагментов вместо других, при помощи регулярных выражений. Оператор tr/…/…/ заменяет выходной текст, но при этом он не использует регулярные выражения, осуществляя замену посимвольно.
Оператор m/шаблон/ — поиск подстроки по определенному шаблону. Например print «$1 г.n» while m!((d){4})!g найдет и выведет все даты в переменной $_. В шаблоне не важно, что будет его ограничителем. Например при поиске гиперссылок, которые зачастую содержат символы /, разумнее пользоваться не /, а например # или ! как символами ограничителями. В таком случае шаблон будет более прост для понимания другим программистам, да и немного короче. В perl оператор m/…/ используется очень часто, и поэтому используется сокращение, без начальной буквы m. Если начальная буква есть, то в качетсве символов ограничителей можно исползовать любой другой символ.
Для оператора m/pattern/ есть 6 параметров: gimsxo
m/foo/g говорит компилятору найти все foo в тексте, в то время как m/foo/ найдет только первое вхождение подстроки foo в строке $_. В строке $_ содержится обычный текст, как и в переменной $text$, $_ такая-же переменная, только она существует всегда и вводится, когда не определена специально другая, по умолчанию.
Например можно сказать for (@mass){print $_,»n»} или for $elem (@mass){print $elem,»n»}. Эти две строчки делают одно и то-же, но в первом случае запись короче, да и зачастую бывает удобно использовать переменную $_, например, когда нужно выделить при помощи регулярного выражения определенные данные, пользуясь перебором массива(функция map):
@res=map{/(dddd)/} split /s/, $texts; что эквививалентно коду push @res, $1 while m!((d){4})!g; #(в данном случае $_=$texts) или что эквивалентно конструкции foreach(split /s/, $texts){ push @res, $1 if(/(dddd)/g) }
Следующий параметр m/foo/i, говорит о том, что не нужно учитывать регистр при поиске по подстроке.
Параметр m/foo/s говорит от том, что строка, по которой производится поиск, состоит из одной строчки.
Например нужно выцепить все url картинок из странички www.astronomynow.com, чтобы сделать локальное зеркало этой странички и пользователи могли с интересом читать последние новости астрономии:
#!/usr/bin/perl -wT use LWP::Simple; $page=get «http://www.astronomynow.com»; &getlink($page); sub getlink{ local $_=$_[0]; push(@res, «http://$2») while m{SRCs*=s*([«‘])http://(.*?)1s*(.*?)WIDTH=»100» HEIGHT=»100″(.*?)>}igs }
В подпрограмме заводится при помощи функции local переменная, видимая только в области действия подпрограммы. Этой переменной присваивается значение переменной $page, в которой содержится текст выкачанной Simple.pm странички.
Можно сделать немного по другому, сохранить скачанную страничку в файл на диск и затем следующее:
$/=»