Прекрасный язык Perl

Автор: manager Среда, Апрель 2nd, 2008 Нет комментариев

Рубрика: CGI-программирование

Вы наверное обратили свое внимание что CGI скрипты пишутся обычно на языке Perl (Practical Extraction and Report Language)- очень удобном языке,впитавшем из других все лучшие черты.Может у вас возникнуть сомнение :Ну вот!Изучать новый язык программирования!? Спешу вас успокоить,изучение Perl не будет в тягость (я сужу по своему опыту!). Вы даже сами не заметите как выучите его.Если вы хоть когда-нибудь программировали скажем на C и использовали утилиту grep для поиска регулярных выражений в тексте,то вам будет еще легче.Мое изучение Perl началось с того что я скачал Perl подWindows (фирмы ActiveWare) и изучения той HTMLой документации которая к нему прилагалась хватило чтоб этот язык стал моим любимым….
Все в нем сделано для удобства программиста (в отличии например от Java;( )
Начнем с переменных,они в Perl бывают 3х типов скаларные,списковые(массивы) и хэши(ассоциативные массивы). Для указания компилятору(да и для немалого удобства программиста) перед именем скалярной переменной стоит знак ‘$’ перед массивом ‘@’,перед хешем ‘%’. т.е. например $scalar_var,@array_var,%hash_var Скалярные переменные могут быть как числовые так и строковые,но это не надо указывать Perl сам по контексту в зависимости от операций может привести одно к другому.
Например: «123″+»4″ будет 127 (или «127″) так как операция ‘+’ действует над числами а вот если применить операцию конкатенации строк ‘.’ то строковое «test» . 1 будет «test1″


Ну а вот операции над скалярными переменными:

Операцыи Описание Пример
+ — * / % Арифметические print 2*7+4/(8%3);
print int(127/15); #целая часть
** Возведение в степень print 2**16;
++ — Инкремент-декремент $i++;
& | ^ ~ << >> Побитовые $x=3;$y=4;
print $x|$y;
print $x&$y;
== != < > <= >= <=> Числовые операции сравнения if($x==9){print «Ok!»;}
eq ne lt gt le ge cmp стрковые операции сравнения if($game eq ‘doom’){print «You are doomer!\n»;}
|| && ! Логические if(($x==9)||($game eq ‘doom’)){print «hello you!\n»;}
?: Условный оператор $x=($game eq ‘quake’?9:8);
, Последовательное вычисление $x=10,$y=20;
. Конкатенация $x=’http://’.'www.uic.nnov.ru’;
x Повторение $x=’1234′x5; #$x=’12341234123412341234′
=~ Сопоставление с образцом if($url=~/http/){print «HTTP»;}
!~ То же но с отрицанием if($url!~/http/){print «No HTTP»;}
= += -= *= /= %= **= |= &= ^= ~= <<= >>= .= x= Присваивание $x+=$y;


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

$x='qwerty';
print 'my var is $x'; #выведет my var is $x
print "my var is $x"; #выведет my var is qwerty

Списки: Спискочные переменные начинаются с символа ‘@’ конструируются следующим образом

@List1=(1,2,5,70);
@List2=(12,23,@List1); #12,23,1,2,5,70
@Rgb=($r,$g,$b);

Также можно список использовать как lvalue:

@List=(1,2,3..8,15);
($x,$y,$z)=@List;        #$x=1,$y=2,$z=3
($x,$y,$z,@list2)=@List; #$x=1,$y=2,$z=3,@list2=(4,5,6,7,8,15);
($r,$g,$b)=@Rgb;

Можно обращаться к нескольким,выбраным элементам массива(срезу массива):

@list=(1..10);
@list[2,3,5,9]=(100,200,300,400); #@list=(1,100,200,4,300,6,7,8,400,10)
@list[1,10]=@list[10,1];#меняет местами элементы

Обратится к скаларному значению -элементу массива можно $имя_массива[индекс], сдесь обратите внимание на знак ‘$’- мы ведь обращаемся к скаляру-элементу.
Теперь немного о хешах:
хеш это такой массив который состоит из пар ключ-значение, весь хеш обозначается %хеш ,к отдельным элементам доступ$хеш{скалярное выражение} конструируется хеш так:

$my_hash{1}="doom";
$my_hash{'quake'}="www.idsoftware.com";
$my_hash{1+2}=100;

Хеш может быть также сконструирован из массива с четным числом элементов где пары превращаются в ключ-значение

%hash=(1,20,2,100);#аналогично $hash{1}=20;$hash{2}=100;

удаление из хеша -операция delete:

delete $hash{1};

есть функции выдающие ключи и значения соответственно.

%hash=(1,20,2,100,3,'doom');
@k=keys %hash;  #@k=(1,2,3);
@v=values %hash;#@v=(20,100,'doom');

Операторы:
Набор операторов в Perl Очень широк,многие из них прямые аналоги имеющихся в других языках,например if,for,while;но есть и значительные улучшения имеюшихся и конечно новые…
Тот же самый оператор if имеет две формы (как когда удобнее):

if(условие)оператор;
оператор if условие;

В пару к оператору if имеется оператор unless : означающий if с отрицанием:

unless(($method eq 'GET')||($method eq 'POST')){print "Unsupported method";}
print "Ok" unless $x < $y;

Также в пару while существует until
синтаксис оператора for полностью аналогичен C:

for($i=0;$i<10;$i++){
print $i;
}

новшеством(и приятным) является foreach позволяющий пройтись по всем элементам массива,присваивая по очереди его элементы какой-то переменной, его синтаксис такой:

foreach $переменная (@массив){
блок операторов;
}
или
foreach (@массив){
операторы;
}

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

следующий пример
@Data=<STDIN>;
foreach(@Data){
chomp;
print if /^From:/;
}
аналогичен такому:
@Data=<STDIN>;
foreach $_ (@Data){
chomp($_);
print $_ if $_ =~ /^From:/;

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

if(/abc/){
print '$_ содержит abc\n';
}

это самый простой пример применения регулярного выражения а теперь посложнее вот тут в табличке (из того что я помню наизусть):

Символ Значение Пример применения
. Соответствует любому символу print if /ab.c/;
[мн-во симв] Соответствует любому символу из данного мн-ва /[abc]d/;#соответствует ad,bd,cd
[^мн-во] Отрицание мн-ва символов /[^xyz]/;#
(….) Группировка элементов(и также запоминание в переменных $1 $2 $3 …) /(xyz)*/
/([abc].[^xy]qwerty)/
(..|..|..) Одна из альтернатив
* повторение образца 0 или более раз /.*/;#соответствует всему
? Повторение 0 или 1 раз /(http:\/\/)?.*\.cgi/
+ Повторение 1 или более раз
{n,m} повторение от n до m раз
{n} повторение точно n раз
{n,} повторение n и более раз
Спец символы:
\t \r \n … Управляющие символы:табуляции,возврат каретки,перевод строки…..
\d Соответствует цифре,Аналог [0-9]
\D Соответствует нецифровому симсволу,аналог[^0-9]
\w Соответствует букве
\W Соответствует небуквеному символу
\s Соответствует пробельным символам(пробелы,табуляции,новые строки..)
\S Соответствует непробельному символу
\b Соответствует границе слова $test1=»this is test»;
$test2=»wise»;
if($test1=~/\bis\b/){print «1″;}#соответствует
if($test2=~/\bis\b/){print «2″;}#нет
\B Соответствует не границе слова /\Bis\B/ соответсвует ‘wise’ но не ‘is’

Для того чтоб поместить в регулярное выражение любой специальный символ,поставьте реред ним обратный слэш ЗаставитьPerl игнорировать регистр можно поставив i после регулярного выражения

print "Are you sure?:";
$answer=<STDIN>;
if($answer=~/Y/i){
#че-нибудь сделаем...
}

Полезные функции.
В Perl очень много различных функций ,как говорится на все случаи жизни,все о них я конечно не опишу,но обо многих. Начну с тех,которые больше относятся к операторам. Операция замены s/рег.выражение/строка/ игнорировать регистр — опция i глобальная(по всей строке) замена -опция g; Пример:

 $x="This is test";
$x=~s/ /_/g;
print $x; #This_is_test

Очень полезная опция у s/// e -она означает что вторая строка не строка а выражение, результат которого и будет подставлен. Например,у вас есть файл в котором все записи о возрасте через год надо менять

 open OLD,"oldfile.txt" || die "Cannot open oldfile.txt $!\n";
open NEW,">newfile.txt" || die "Cannot open newfile.txt $!\n";
foreach(
){
s/(\d+)(\s+год)/($1+1).$2/gie;
s/(\d+)(\s+лет)/($1+1).$2/gie;
print NEW $_;
}
close NEW;
close OLD;

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

sub urldecode{
local($val)=@_;
$val=~s/\+/ /g;
$val=~s/%([0-9A-H]{2})/pack('C',hex($1))/ge;
return $val;
}

Также важным удобством в Perl являются операции для работы с файлами для выполнения схожих функций в других языках приходиться проделывать огромную массу работы. Аргументами могут быть как Файловые переменные,так и строки,представляющие имя файла.

Операция Описание Пример использоввания
-r Доступен для чтения unless(-r «myfile»){print «Cannot read myfile\n»;}
-w Доступен для записи
-x Для исполнения
-o Принадлежит пользователю if(-o «index.htm»){chmod 0777,»index.htm»;}
-R Доступен для чтения реальным
пользователем,а не только «эффективным».
Имеет значения для set-uid -скриптов
if(-r FILE){unless(-R FILE){die «Its not allowed to read this\n»;}}
-W Доступен для записи реальным пользователем
-X Доступен для исполнения реальным пользователем
-O Принадлежит реальному пользователю
-e Файл или каталог Существует unless(-e $htmlfile){
open HTML,»>$htmlfile»;
print HTMLFILE «<HTML><BODY></BODY></HTML>»;
close HTMLFILE;
}
-z Существует,но имеет нулевую длину if(-z ‘tmpfile’){unlink ‘tmpfile’;}
-s Размер файла в байтах system «rar m -m5 archive.rar $myfile» if -s $myfile > 1000;
-f Файл существует и является простым файлом
-d Файл существует и является каталогом if(-d ‘public_html’){chdir ‘public_html’;}
-l Символической ссылкой
-p Каналом FIFO
-u Имеет бит установки пользователя
-g Имеет бит установки группы
-k Установлен sticky-бит
-t Является терминальным устройством
-M Время с последнего изменения (в днях) while(defiled($file=glob(‘*’))){
if(-M $file >= 7.0){
unlink($file);#удаляем слишком старые файлы
}
}
-A Время последнего доступа(в днях) if(-A «$ENV{‘HOME’}/public_html/index.html» < -A «$ENV{‘HOME’}/.last»){print «Кто-то ходил на твою домашнюю страничку пока тебя не было!!!\n»;}
-C Время последнего обновления файлового индекса(в днях)

Еще есть и другие
функция open открывает файл

open ФАЙЛОВАЯ_ПЕРЕМЕННАЯ,"имя файла";  #открыть файл для чтения
open ФАЙЛОВАЯ_ПЕРЕМЕННАЯ,">имя файла"; #для записи
open ФАЙЛОВАЯ_ПЕРЕМЕННАЯ,">>имя файла";#для записи в конец
open ФАЙЛОВАЯ_ПЕРЕМЕННАЯ,"+<имя файла";#для чтения и записи
open ФАЙЛОВАЯ_ПЕРЕМЕННАЯ,"|комманда";  #направить информацию на вход программы
open ФАЙЛОВАЯ_ПЕРЕМЕННАЯ,"комманда|";  #считать информацию с выхода программы
open ФАЙЛОВАЯ_ПЕРЕМЕННАЯ,"|комманда|"; #и то и другое вместе

Что какается открытия файлов,то вам как програмистам все очевидно, но с коммандами тоже все здорово,что пояснит хороший пример(из практики):

open MAIL,"|mail paaa@uic.nnov.ru";#Пошлем информацию по почте
print MAIL "Hello\n";
print MAIL "...\n";
print MAIL "...\n";
close MAIL;

когда вы открыли файл вы можете считать из него строку в скалярную переменную Вот так:$str=<FILE>
избавиться от символа новой строки на конце поможет функция chomp, ведь этот символ может помешаться например в имени файла или при выводе на экран

print "Введите имя файла:";
$fname=<STDIN>;
chomp($fname);
open F,$fname || die "Cannot open $fname $!\n";
.....

Если также подставить списочную переменную,то получим список строк файла от текущей строки и до конца

print "Что искать:";
$search=<STDIN>;
chomp($search);
@L=<F>;
foreach(@L){
print if /$search/;
}
а можно и так:
print "Что искать:";
$search=<STDIN>;
chomp($search);
foreach(<F>){
print if /$search/;
}

бинарный файл можно читать и писать функциями sysread и syswrite:
sysread ФАЙЛОВАЯ_ПЕРЕМЕННАЯ,$скалярная_перемменая,сколько_байт
syswrite ФАЙЛОВАЯ_ПЕРЕМЕННАЯ,$скалярная_перемменая,сколько_байт
функции split и join@Список=split /рег.выр/,$скаляр;
$скаляр=join строка,@Список;

#Разбить строку слов,разделенных пробелами в список вы можете
@WordList=split / /,$String;
#После обработки снова обьединить
$String=join ' ',@WordList;

Встроеные функции Perl можно вызывать со скобками или без (как вам удобно), скобки программисты указывают или для красоты,или чаще,что устранить возможную неоднозначность в выраженнии:

printf "x=%d",$x;
printf ("x=%d",$x);#аналогично

Надеюсь что я вас позабавил примерами функций ;) .
Примеры применения Perl для различных нужд…
Следующая программа переводит текстовый файл в формат HTML (вспомните сколько хлопот вам доставит отлов во всем файле ‘<’, ‘>’ и ‘&’ чтоб заменить их на &tl; , &gt; и &amp; а как неплохо чтоб автоматически все http://www…. превратились в<A href=»http://www….» >http://www….</A>)

#!/usr/bin/perl
#txt2html
die "Usage: txt2html Infile OutFile\n" unless(@ARGV);
open IN,"$ARGV[0]" || die "Cannot open $ARGV[0] $! \n";
open OUT,">$ARGV[1]" || die "Cannot open $ARGV[1] $! \n";
while(<IN>){
s/&/&amp;/g;
s/</&lt;/g;
s/>/&gt;/g;
s/\n/<BR>\n/g;
s/(http:\/\/\S+)/<A href="$1">$1<\/A>/g;
print OUT $_;
}
close IN;
close OUT;

 

Оставить комментарий

Чтобы оставлять комментарии Вы должны быть авторизованы.

Похожие посты