Современные технологии разработки программного обеспечения

Язык Perl

Показывать лекцию целиком

Презентация к лекции

Perl - высокоуровневый интерпретируемый динамический язык программирования общего назначения, созданный Ларри Уоллом, лингвистом по образованию. Название языка представляет собой аббревиатуру, которая расшифровывается как Practical Extraction and Report Language "практический язык для извлечения данных и составления отчётов "

Сейчас Perl содержится практически в каждом дистрибутиве Linux и других UNIX-систем, портирован на Windows и многие другие платформы. Администраторы со всего мира используют его для автоматизации своих повседневных задач.

Репозиторий CPAN содержит множество модулей для языка буквально на все случаи жизни.

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

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

#!/usr/bin/per

Эту строку желательно использовать как под Linux, так и под Windows (вдруг скрипт придётся на сервер заливать). Без данной строки программа не будет выполняться.

В структуру Perl'а входят: переменные, операторы, специальные символы. Все переменные начинаются с символа "$ " - как символьные так и числовые. Задаются переменные следующим образом:

$a=10; # Числовая переменная $b= "simvol "; # Символьная переменная

Как численные, так и символьные переменные являются скалярными переменными. Рассмотрим действия, которые можно производить над скалярами:

Стоит отметить разницу между апострофами и кавычками, использующихся в присваивании. В кавычках осуществляется подстановка переменных и спец. символов, а в апострофах нет.

Чтобы игнорировать подстановку в кавычках, следует перед спец. символом поставить слеш ( \ ).

$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 ');
  • Операторы

    Оператор 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= ; foreach(@data) { chomp; print if /^From:/; } 

    аналогичен такому:

     @data= ; 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 "; }

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

    Опция g осуществляет замену по всей строке (глобальная замена). Опция e используется для подстановки в выражение второй строки полностью. Рассмотрим пример замены:

    $x= "This is test "; $x=~s/ /_/g; print $x; # Выведет "This_is_test "

    Функции split и join

    Регулярные выражения можно использовать для разбивки строки на поля. Это делает функция split. Функция join выполняет противоположное действие - вновь "склеивает " эти кусочки.

    Функция split

    Функция split получает регулярное выражение и строку и ищет в этой строке все экземпляры указанного регулярного выражения. Те части строки, которые не совпадают с регулярным выражением, возвращаются по порядку как список значений.

    Вот, например, код синтаксического анализа разделенных двоеточиями полей, аналогичных тем, которые используются в UNIX-файлах /etc/passwd:

     $line = "merlyn::118:10:Randal:/home/merlyn:/usr/bin/peri "; @fields = split (/:/,$line); # разбить $line, используя в качестве t разделителя двоеточие # теперь @fields содержит ( "merlyn ", " ", "118 ", "10 ", # "Randal ", "/home/merlyn ", "/usr/bin/peri ")

    Обратите внимание на то, что второе пустое поле стало пустой строкой. Если вы этого не хотите, задайте сопоставление следующим образом:

    Sfields = split(/:+/, $line);

    Здесь при сопоставлении принимаются во внимание одно и более расположенных рядом двоеточий, поэтому пустое поле не образуется.

    Очень часто приходится разбивать на поля значение переменной $_, поэтому этот случай предлагается по умолчанию:

    $ = "some string "; Swords = split (/ /); # то же самое, что и Swords = split(/ /, $_); * # Или две пары, если используется символ из пары "левая-правая "

    При такой разбивке соседние пробелы в разбиваемой строке вызовут появление пустых полей (пустых строк). Лучше использовать образец / +/, а лучше /\s+/, который соответствует одному и более пробельным символам. Этот образец, по сути дела, используется по умолчанию *, поэтому, если вы разбиваете переменную $_ по пробельным символам, вы можете использовать все стандартные значения и просто написать :

    Swords = split; # то же самое, что и (Swords = split(/\s+/, $_) ;

    Завершающие строки пустые поля в список, как правило, не включаются. Особой роли это обычно не играет. Решение вроде $line = "merlyn::118:10:Randal:/home/merlyn: "; ($name,$password,$uid,$gid,$gcos,$home,$shell) = split(/:/,$line); # разбить $line, используя в качестве разделителя двоеточие просто присваивает переменной $shell нулевое значение (undef), если эта строка недостаточно длинна или содержит в последнем поле пустые значения. (Разбиение выполняется так, что лишние поля просто игнорируются.)

    Функция join

    Функция join берет список значений и "склеивает " их, ставя между элементами списка строку-связку. Выглядит это так:

    $bigstring = join($glue,@list);

    Например, чтобы восстановить строку пароля, попробуйте использовать следующее:

    $outline = join( ": ", @fields) ;

    Отметим, что строка-связка - это не регулярное выражение, а обычная строка, состоящая из символов общим числом нуль или более.

    Если нужно поставить связку не между элементами, а перед каждым элементом, то достаточно такого трюка:

    $result = (join "+ ", " ", @fields);

    Здесь пустая строка " " рассматривается как пустой элемент, который должен быть связан с первым элементом данных массива @fields. B результате связка помещается перед каждым элементом. Аналогичным образом можно поставить пустой элемент-связку в конец списка:

    $output = join ( "\n ", @data, " ");

    * На самом деле образец по умолчанию - строка " ", поэтому начальный пробельный разделитель игнорируется.

    Основные операции с числами и строками

    Операции (также называемые операторами) в Perl многочисленны и разнообразны, с их помощью образуются арифметические, логические, строковые и другие выражения - конструкции, вычисляющие некоторый результат, хотя он не всегда может использоваться. Элементы выражения, над которыми производится операция, называются операндами. Результат операции в Perl может зависеть от контекста, в котором она выполняется. Но часто и сама операция устанавливает определенный контекст, влияющий на преобразование операндов. Конкретные правила вычисления выражений будут изложены при подробном рассказе о каждой из операций.

    Конечно же, в Perl, как и в других языках программирования, есть традиционные арифметические операции:

  • * умножение (например, 2 * 2 будет 4)
  • / деление (например, 11 / 2 будет 5.5)
  • + сложение (например, 111 + "999 " будет 1110)
  • - вычитание (например, '26 ' - 1 будет 25)
  • В Perl есть еще две очень удобные арифметические операции, которые имеются не во всех языках программирования:

  • ** возведение в степень (например, 2 ** 5 будет 32)
  • % деление по модулю или остаток от деления (например, 11 % 3 будет 2)
  • В Perl есть отдельные наборы операций для сравнения чисел и строк. Обозначения операций сравнения чисел совпадают с обозначениями операций в других языках, основанных на синтаксисе языка C. В следующих примерах предположим, что в переменной $n хранится значение 25:

  • == равно (не путайте с присваиванием (=), например, $n == 4 ложно)
  • != не равно (например, $n != 8*2 истинно)
  • < меньше, чем (например, $n < '16.08 ' ложно)
  • > больше, чем (например, $n > 9 истинно)
  • меньше или равно (например, $n <= 26 истинно)
  • больше или равно (например, $n >= 24 истинно)
  • <= > числовое сравнение (например, $n <= > 64 вернет -1)
  • Обозначения операций сравнения строк похожи на обозначения сравнений в языке программирования Fortran. Они применяются, когда сравниваемые величины нужно рассматривать как строки. При сравнении строковых значений учитывается их положение в кодовой таблице символов: чем ближе к началу таблицы, тем меньше значение. В следующих примерах предположим, что в переменной $s хранится 'a ':

  • eq равно (например, $s eq 'a ' истинно)
  • ne не равно (например, $s ne 'Y ' истинно)
  • lt меньше, чем (например, $s lt 'z ' истинно)
  • gt больше, чем (например, $s gt '9 ' истинно)
  • le меньше или равно (например, $s le 'b ' истинно)
  • ge больше или равно (например, $s ge 'Z ' истинно)
  • cmp строковое сравнение (например, $s cmp 'Z ' вернет результат 1)
  • Последняя операция строкового сравнения cmp, так же, как операция числового сравнения <= > , возвращает одно из значений: - 1, 0 или 1, если первый операнд операции соответственно меньше, равен или больше второго. При сравнении строк имеет значение их длина и содержащиеся в них пробелы: равными считаются посимвольно совпадающие строки одинаковой длины. Операции сравнения строк устанавливают строковый контекст, поэтому их числовые операнды преобразуются к строкам. При этом строковое сравнение чисел дает своеобразный результат, например, '20 ' больше '100 ', поскольку '2 ' находится в таблице символьных кодов позже, чем '1 '. Проверка на частичное совпадение строк, которая часто требуется при обработке текста, выполняется с помощью регулярных выражений.

    Перечень операций в языке Perl не ограничивается рассмотренными в этой лекции. По мере изучения других разделов будут описаны другие, более специализированные операции. Например, нам наверняка понадобится операция чтения строки из стандартного входного потока (обычно связанного с системной консолью). Она обозначается символами < > и по- английски называется diamond, что на русский лучше всего перевести как "кристалл " (хотя встречается русское название "ромб "). Эта операция считывает очередную строку и возвращает ее значение: $line = < > # считать в $line строку из стандартного ввода.

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

  • $a ** $b ** $c # ассоциативность справа, т.е. $a**($b**$c)
  • $a * $b / $c # ассоциативность слева, т.е. ($a * $b) / $c
  • $a && $b && $c # ассоциативность слева, т.е. ($a && $b) && $c
  • $a = $b = $c # ассоциативность справа, т.е. $a = ($b = $c)
  • $a | $b ^ $c #, ассоциативность слева, т.е. ($a | $b) ^ $c
  • В Perl имеется большое количество операций, в том числе и весьма экзотических. Поэтому, если возникает сомнение в порядке их вычислений, то всегда можно использовать скобки для управления очередностью вычислений в выражении.

    Вернуться к учебному плану