На главную

  • Вступление

    Откуда появился язык Perl и как он расшифровывается? Перед тем как осваивать язык программирования нужно знать хотя бы общие сведения о нём.
    Perl создал некий Ларри Уолл. Perl - аббревиатура, расшифровывается как Practical Extraction and Report Language (практический язык извлечений и отчётов).
    Данная статья не научит вас в совершенстве владеть Perl`ом. Для этого нужен многолетний опыт и огромные знания. Тут я отражу лишь общие сведения по теме, чтобы вы могли оттолкнуться от них и изучать язык более углублённо.
    Ещё следует добавить, что в этой статье нет изучения дополнительных модулей для Perl. Информацию о них ищите в главе "Сайты".
    Если у вас ещё не пропало желание читать статью, то вперёд!


  • Структура языка

    Все Perl-программы должны начинаться со строки, указывающей путь к Perl-интерпретатору. Эта строка обычно выглядит так:
    #!/usr/bin/perl
    Эту строку желательно использовать как под Linux, так и под Windows (вдруг скрипт придётся на сервер заливать). Без данной строки программа не будет выполняться.

    В структуру Perl`а входят: переменные, операторы, специальные символы. Все переменные начинаются с символа "$" - как символьные так и числовые. Задаются переменные следующим образом:
    $a=10;   # Числовая переменная
    $b="simvol";    # Символьная переменная
    
    Как численные, так и символьные переменные являются скалярными переменными. Рассмотрим действия, которые можно производить над скалярами:

    Операция Описание Примеры
    + . / % Арифметические действия
    print 2*7+4/(8%3);
    print int(127/15); #Целая часть
    
    ** Возведение в степень
    print 2**16;
    ++ -- Инкремент и декремент
    $i++; # Увеличить переменную $i на 1
    & | ^ ~ << >> Побитовые операции
    $x=3; $y=4; print $x|$y;
    print $x&$y;
    == != < > <= >= <=> Числовые операции сравнения
    if ($x==9) { print "Ok!"; }
    eq ne lt gt le ge cmp Строковые операции сравнения
    if ($test eq 'ok') { print "All right!"; }
    || && ! Логические операции
    if (($test eq 'ok') || ($x==9) { print "All right!"; }
    , Последовательное вычисление
    $x=10,$y=20;
    . Склеивание
    $url='http://'.'rambler.ru';
    x Повторение
    print '1234'x3; # Получится '123412341234'
    =~ !~ Сопоставление с шаблоном
    if ($url=~/http/) { print "HTTP"; }
    = =+ =- *= /= %= **= |= &= ^= ~= <<= >>= .= x= Присваивание
    $x+=$y; # Прибавит к переменной $x переменную $y
    

    Стоит отметить разницу между апострофами и кавычками, использующихся в присваивании. В кавычках осуществляется подстановка переменных и спец. символов, а в апострофах нет. Чтобы игнорировать подстановку в кавычках, следует перед спец. символом поставить слеш ( \ ).
    $x='perem1';
    print 'Var = $x'; или print "Var = \$x"; # Выведет 'Var = $x'
    print "Var = $x"; # Выведет 'Var = perem1'
    

  • Массивы

    Массивы начинаются с символа @ и конструируются следующим образом:
    @array1=(1,2,3,4,5);
    @array2=(30,40,@array1); # Добавление к @array2 всех элементов @array1
    @array3=($perem1,$perem2,$perem3);
    
    Обращение к элементам массива осуществляется так:
    @array1=(1..20);
    @array1[2,10,20]=(20,3,4); # Замена элементов под номерами 2 10 и 20 числами 20 3 и 4
    @array1[20,1]=@array1[1,20] # Меняет элементы местами
    
    Обращаться к отдельному элементу массива (скаляру) можно в форме $имя_массива[индекс].
    Для массивов существуют также такие функции как push(), pop(), shift(), unshift().
    push(@array1,$perem1); # Добавляет $perem1 в конец @array
    unshift(@array,$perem1); # Добавляет $perem1 в начало @array
    $perem1=pop(@array1); # Присваивает $perem1 последнему элементу массива @array
    $perem1=shift(@array); # Тоже самое с первым элементом
    

  • Хэши

    Хэш - массив, состоящих из пар "Ключ-значение". Доступ к каждому значению записи осуществляется по ассоциированному с ним ключу. Хэш выглядит так: %имя_хэша. Доступ к оттедльным его элементам: $имя_хэша{выражение}.
    Кострукция хэша выглядит следующим образом:
    $hash{1}="key1";
    $hash{'myset'}="www.rambler.ru";
    $hash{1+2}=50;
    
    %hash(1,20,2,100); # Чётное кол-во элементов обязательно! 
    # Запись аналогична $hash{1}=20; $hash{2}=100;
    
    Удаление элементов из хэша производится с помощью операции delete:
    delete($hash{1});
    Выделить отдельные ключи и значения хэша можно при помощи функций keys() и values() соответственно:
    %hash(1,20,2,100,3,'test');
    @key=keys(%hash); # @key=(1,2,3);
    @value=values(%hash) # @value=(20,100,'test');
    
    
  • Операторы

    Наконец, мы подошли к изучению операторов Perl. Набор операторов в нём огромен. Мы рассмотрим самые важные и простые.

    Оператор if имеет 2 формы:
    if(условие)оператор;
    оператор if условие;
    
    В пару к if имеется оператор unless означающий if с отрицанием:
    unless(($method eq "GET")||($method eq "POST")) {
    print "Unknown method";
    }
    print "Ok" unless $y > $x;
    
    Также и с циклическим блоком while. Ему в пару существует оператор until означающий отрицание while. Например вместо:
    while(!eof(FILE)) {
    # Операторы ...
    }
    
    можно написать:
    until(eof(FILE)) {
    # Операторы ...
    }
    
    Синтаксис оператора for выглядит следующим образом:
    for($i=0;$i<10;$i++) { # Выходим из цикла при $i<10
    print $i; # Начальное значение $i=0
    } # При каждой прокрутке цикла увеличиваем $i на 1
    
    Следующий оператор foreach предназначен специально для массивов и предоставляет возможность пройтись по всем его элементам, поочерёдно присваивая каждый элемент каой-то переменной:
    foreach $переменная (@массив) {
    # Операторы...
    }
    
    или
    foreach (@массив) {
    # Операторы
    }
    
    В последнем примере используется особенность Perl - переменная по умолчанию $_. Именно ей присваивается каждый элемент массива. Данная переменная сопоставляется и с регулярными выражениями, например фрагмент кода:
    @data=<STDIN>;
    foreach(@data) {
    chomp;
    print if /^From:/;
    }
    
    аналогичен такому:
    @data=<STDIN>;
    foreach $_ (@data) {
    chomp ($_);
    print $_ if $_=~/^From:/;
    }
    
  • Регулярные выражения

    Пожалуй самым большим преимуществом языка Perl над другими является поддержка регулярных выражений.
    Синтаксически регулярное выражение записывется между слэшами: /regular/.

    Вот самый простой пример применения регулярных выражений:
    if (/abc/) {
    print "$_ содержит abc\n";
    }
    
    А вот пример посложнее:
    if(/(ftp|http):\/\/([^\/]+)(.*)/){
    print "Протокол: $1\n";
    print "Сервер: $2\n";
    print "Документ: $3\n";
    }
    
    Рассмотрим специальные символы, входящие в регулярные выражения:

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

    С помощью регулярных выражений можно также производить замену одних символов другими. Синтаксис замены: s/выражение/строка/;

    Опция g осуществляет замену по всей строке (глобальная замена). Опция e используется для подстановки в выражение второй строки полностью. Рассмотрим пример замены:
    $x="This is test";
    $x=~s/ /_/g;
    print $x; # Выведет "This_is_test"
    
  • Работа с файлами

    Для того, чтобы открыть файл используется функция open(). Её формат: open(переменная,"[способ открытия]путь к файлу");. Под переменной впоследствии будет пониматься символьное обозначение файла. Для закрытие файла используем close(переменная).

    Способов открытия для файла несколько. Наиболее важными являются:
    open(myfile,"myfile"); # Открыть файл для чтения
    open(myfile,">myfile); # Открыть файл для записи
    open(myfile,">+myfile); # Открыть файл для чтения и записи
    open(myfile,">>myfile); # открыть файл для дозаписи
    
    Открыв файл, вы можете считать из него строку в переменную:
    $str=<переменная>; # Где переменная соответствует переменной, обьявленой в open() 
    или весь файл в массив:
    @str=<переменная>;
    
    Избавиться от символа перехода на новую строку, поможет функция chomp($переменная).

    Вписать что-либо в файл можно стандартным оператором print: print переменная "text"; Вот простой пример, который выводит содержимое файла на экран:
    open(passwd,"/etc/passwd");
    while ($read=<passwd>){
    print "$read\n";
    }
    close(passwd);
    
    Для удаления файла используется функция unlink("имя_файла"), для переименования: rename("имя_файла","новое_имя_файла");

    Следующие операции осуществляют проверку над файлами:
    -e - файл или каталог существует.
    if(-e "file") {print "Yes"; }
    -z - файл существует и имеет нулевую длину.
     if(-z "tmp") { unlink("tmp"); }
    -d - файл является каталогом.
    if(-d "myfile") { chdir("myfile"); }
    -s - размер файла в байтах.
    unlink("file") if (-s "file" < 20);

  • Другие полезные функции
  • Рассмотрим другие, очень полезные функции. В первую очередь такими являются split() и join(). Они помогают разбить или склеить строку по определённым символам.
    @massiv=split(/:/,$str); # Разбивает строку по ":"
    print "$massiv[0]\n"; # Печатает первый элемент, стоящий перед ":" в строке
    $str=join(/;/,@massiv); # Склеивает все элементы массива по ";"
    
    Функция substr() позволяет выделить часть строки. Формат функции:
    substr($строка,начальный номер элемента,конечный номер элемента);
    $str1=substr($str,0,7); # Присваивает $str1 первые 7 элементов $str;
    
    Функции lenght и scalar позволяют узнать количество символов в строке и количество элементов в массиве соответственно:
    $count=lenght($str); # Возвращает кол-во символов в $str
    $arr=scalar(@array); # Возвращает кол-во элементов в массиве @array
    

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

    http://www.perl.com/ <-- главный сайт по Perl-программированию.
    http://www.cgi-resources.net/ <-- бесплатные скрипты и документация.
    http://www.nas.pp.ru/ <-- хороший сайт по Perl.

    Удобства Perl: приятные мелочи. Часть 1


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

    if (a == b) { c = d }

    можно записать иначе:

    c = d if a == b;

    Согласись, намного удобнее - лишние составные операторы нам ни к чему :)

    "Волшебные" переменные.

    В Perl`е очень много замечательных переменных, на выделение которых программистом потребовалось бы много времени и кода. Постараюсь перечислить некоторые из них:

    $0 - выделение базового имени программы-скрипта. Часто используют в распечатке флагов использования программы.
    $1 ... $N - переменные, которые обретают свое значение в регулярных выражениях, заключенных в скобки. К примеру после такой строки:

    $var=~/(.*)test-(.*)/;

    значение $1 будет определено любыми символами до слова 'test', а $2 - после 'test-'.

    $+ - содержит значение последней переменной для последнего успешного поиска. Это помогает узнать, какой вариант был обнаружен при альтернативном поиске, например для

    /(x,*y)|(y.*z)/

    в переменной $+ будет хранится содержимое $1 или $2 (в зависимости от результата поиска).

    $/ - Переменная разделения записей.

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

    open(FILE,"file.txt");
    undef $/ # Уничтожаем $/
    while (<FILE>) { $bigstring=$_ }
    close(FILE);

    $_ - переменная по-умолчанию.

    Играет огромное значение и не обременяет программиста созданием новых дополнительных переменных. Хранит в себе текущий обрабатываемый элемент (актуальна для циклов). В ряде случаев ее вообще можно пропускать.

    Например

    while (<FILE>) {
    chomp $_;
    print "$_"
    }

    можно записать проще:

    while (<FILE>) {
    chomp;
    print
    }

    Подразумевается, что параметром вызываемых процедур является $_.

    $! - переменная последней ошибки.

    Хранит в себе последнюю ошибку. Удобна в случае, когда необходимо узнать, что помешало открыть файл // прочитать данные и т.п. , например:

    open(testfile,"test.txt") || die print "$!\n";

    Вот пожалуй наиболее популярные так называемые, волшебные переменные. Их значение я уже называл чуть выше.

    В следующей части я рассмотрю некоторые полезные регулярные выражения и процедуры мощьщнейшего языка Perl.

    Вопросы? Пишите на e-mail. Постараюсь ответить.

    Удобства Perl: приятные мелочи. Часть 2


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

    1) Выделение ip-адреса.

    Допустим, тебе нужно проверить, является ли строка IP-адресом. Это можно сделать, как простой проверкой:

    if ($string=~/(.*)\.(.*)\.(.*)\.(.*)/) { }

    где проверяется наличием 3-х точек (разделителей звеньев ip-адреса),
    так и более полной проверкой:

    if ($string=~/^[01]?\d\d|2[0-4]\d|25[0-5])\.[01]?\d\d|2[0-4]\d|25[0-5])\.[01]?\d\d|2[0-4]\d|25[0-5])\.[01]?\d\d|2[0-4]\d|25[0-5])$/) { }

    где проверяется корректность адреса (на предмет чисел).

    Тебе решать, что использовать :) Это зависит от проги, которую ты пишешь. Если ты пишешь продукт, для всеобщего обозрения :) то ты должен тщательно выполнять проверку входных данных (мало ли какие пользователи будут юзать).

    2) Удаление комментариев C.

    Бывает, что в скрипте идет обработка C кода. Для этого нужно использовать оператор замены, при помощи регулярных выражений. Смысл заключается в удалении символов комментариев /* и */ :

    s{
    /\*
    .*?
    \*/
    } []gsx;

    3) Обработка ini-файла.

    Здесь ini подразумевается как любой конфиг-файл, типа "переменная=значение". Задача - выделить значение из файла. Выделим файловую переменную в $1, а ее значение в $2:

    open(INI,"conf.ini");
    while (INI) {
    chomp;
    ~/(\w+)\s*=\s*(.*)\s*$/
    }
    close(INI);

    Где \w - любое слово, \s - символ пробела. ".*" - любая последовательность символов (не обязательно что переменная и значение не отделяются пробелом от знака равенства).

    4) Проверка операционной системы.

    В перловой переменной $^O хранится полное название твоей операционки. Бывает, что в скрипте нужно узнать, с какой системой работает скрипт. Пользуяюсь переменной, проверяем:

    die "This is windows\n" if $^O = ~/windows/i;

    5) Поиск ссылок в HTML-документах

    Актуальная проблема - найти все ссылки в каком либо html-файле. Использование регулярного выражения значительно все упростит:

    @urls = ~/<a[^>]+?href\s*=\s*["']?([^'" >]+?)[ '"]?>/sgi;

    Суть поиска заключается в выделении всех символов после href= и перед кавычкой или апострофом. Все ссылки после поиска будут в массиве @urls :)

    Вот пожалуй наиболее интересные regexp`ы, про которые я хотел написать.

    Удачи в кодинге


  • Hosted by uCoz