WebMaster/Programming/Perl/
Прекрасный язык Perl.
Вы наверное обратили свое внимание что CGI скрипты
пишутся обычно на языке Perl (Practical Extraction and Report
Language)- очень удобном языке,впитавшем из других все лучшие
черты.Может у вас возникнуть сомнение :Ну вот!Изучать новый язык
программирования!? Спешу вас успокоить,изучение Perl не будет
в тягость (я сужу по своему опыту!). Вы даже сами не заметите
как выучите его.Если вы хоть когда-нибудь программировали скажем
на C и использовали утилиту grep для поиска регулярных выражений
в тексте,то вам будет еще легче. Для Perl родной платформой является
Unix поэтому пользователям PC он мало известен. Мое целенаправленое
доведение Perl до широкой публики началось с того что я скачал
Perl под Windows (фирмы ActiveWare) К нему прилагается отличная
гипертекстовая HTML- документация, даже быстрого просмотра которой
хватит , чтобы начать хорошо и широко использовать его. Хоть он
значительно уступает и по скорости и по эффективности своему Unix'ному
аналогу, все равно самый лучший способ изучить язык это программировать
на нем. Если вы как я дома используете большую часть времени не
Windows а Unix то с изучением Perl у вас вообще не должно быть
особых сложностей. Я же от себя могу сказать, что даже после небольшого
опыта изучения его, он стал моим любимым языком программирования....
Все в нем сделано для удобства программиста (в отличии
например от 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-hA-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(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; , > и &
а как неплохо чтоб автоматически все 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/&/&/g;
s/</</g;
s/>/>/g;
s/(http:\/\/\S+)/<A href="$1">$1<\/A>/g;
print OUT $_;
}
close(IN);
close(OUT);
Более подробную информацию о Perl вы можете получить
по адресам:
http://www.perl.com
http://www.metronet.com/0/perlinfo/perl5/manual/perl.html
http://www.ActiveWare.com/