Co to jest PERL?
PERL jest skrótem od: Practical Extraction and Report Language
Autor: Larry Wall
PERL jest podobny do języka C
PERL jest podobny do języków skryptowych: SHELL, sed, awk
PERL ma liczne wbudowane polecenia i funkcje
Pełna dokumentacja: http://www.perl.com/CPAN
Podręcznik ogólny: man perl
Podręczniki szczegółowe:
man perlsyn - składnia
man perlfunc - funkcje
i inne, wymienione w ogólnym
Składowe programu
Pierwszy wiersz programu musi mieć postać:
#! /usr/bin/perl
W następnych wierszach mogą być:
komentarze, na prawo od znaku #
wyrażenia proste (zakończone średnikiem):
polecenie
wywołanie funkcji
przypisanie
wyrażenia złożone:
warunkowe
pętle
w postaci bloku, ograniczonego parą (zbiorem) nawiasów { }
definicje zmiennych:
skalarnych (liczbowych i tekstowych)
list
tablic
tablic asocjacyjnych
definicje funkcji
definicje formatów
operacje wejścia/wyjścia
Przykład programu
#!/usr/bin/perl
print "To jest pierwszy program w jezyku PERL\n";
print "Jak masz na imie? ";
$imie = <STDIN>;
print "$imie to Twoje imie\n";
print "Koniec programu\n";
exit
Zmienne skalarne
nazwa zmiennej zaczyna się od znaku $
zmienne skalarne mogą przechowywać:
liczby całkowite
liczby zmiennoprzecinkowe
napisy, ograniczone apostrofami ' (bez interpretacji znaków specjalnych) lub cudzysłowami " (z interpretacją znaków specjalnych)
Operatory skalarne
operatory liczbowe: + - * / % += ++ **
operatory napisowe: .
operatory porównania:
typ porównania |
dla liczb |
dla napisów |
równy |
== |
eq |
nierówny |
!= |
ne |
mniejszy |
< |
lt |
większy |
> |
gt |
mniejszy lub równy |
<= |
le |
większy lub równy |
>= |
ge |
zgadza się |
|
=~ |
nie zgadza się |
|
!~ |
Konwersja liczb i napisów
zmienne są konwertowane automatycznie do typu
odpowiadającemu operatorowi
$z1 = "3koty";
$z2 = "47";
print ($z1 + $z2); # z1 jest konwertowane na 3
$z1 = 34;
$z2 = 47;
print ($z1 . $z2); # z1 i z2 są traktowane jako napisy
print "x" . (3 + 4); # najpierw operacja arytmetyczna, potem
połączenie napisów
Funkcje i operatory skalarne
przypisanie:
$a = 13;
$b = $a + 9;
$d = 3 + (4c = 5);
$e = $f = 8;
$x += 3; to samo co $x = $x + 3;
$y = "ala ma ";
$y .= "kota"; to samo co $y = $y . "kota";
autoinkrementacja (dla liczb całkowitych i rzeczywistych):
$a++; przyrostkowa
++$a; przedrostkowa
funkcje chop i chomp:
chop($zmienna) usuwa ze zmiennej ostatni znak
chomp($zmienna) usuwa znak nowej linii na końcu napisu
<STDIN> jako wartość skalarna
$a = <STDIN>; # przeczytanie wiersza
chomp($a); # usunięcie znaku nowej linii
Funkcja print
print ("ala ma kota\n");
print "ala ma kota\n";
$x = 17;
print $x; # interpretacja znaku $
print '$x'; # bez interpretacji znaku $
print "$x" # interpretacja znaku $
Wartość niezdefiniowana
zmienna skalarna zwracają wartość undef, jeśli są użyte przed nadaniem im wartości; jest to:
0 dla zmiennej liczbowej
pusty napis dla zmiennej napisowej
Listy i tablice
lista jest uporządkowanym zbiorem danych skalarnych
każdy element listy jest identyfikowany przez indeks
składnia zapisu listy: (elem1, elem2, ..., elemn) , np.
(1, 2, 3, 4, 5)
("ala", 3.1, "kot", 5)
($a, 34)
($b + $c, $d * $e)
( )
(1 .. 7, 9 .. 11, 67)
(1.3 .. 6.3)
($a .. $b)
(1.2 .. 5.1) -> (1.2, 2.2, 3.2, 4.2)
zmienna tablicowa przechowuje pojedynczą listę;
@a = ("ala", "ela", "janek"); -> @a = qw(ala ela janek);
Operatory i funkcje tablicowe
przypisanie:
@a = (2, 3 ,4);p # przypisanie listy do zmiennej tablicowej
@b = @a; # kopiowanie
@c = 1; # przypisanie listy (1)
@d = (1, @a, 5, 6); -> @d = (1, 2, 3, 4, 5, 6);
@d = (0, @d, 7); -> @d = (0, 1, 2, 3, 4, 5, 6, 7);
($a, $b, $c) = (1, 2, 3); -> $a = 1; $b = 2; $c = 3;
($a, $b) = ($b, $a); # zamiana wartości
($d, @e) = ($a, $b, $c); -> $d = $a; @e = ($b, $c);
($f, @e) = @e; -> $f = $b; @e = $c;
$a = @d; # przypisanie zmiennej $a długości tablicy @d
($a) = @d; # przypisanie zm. $a pierwszego elem. tablicy @d
Elementy tablicy
elementy tablicy są indeksowane o 0 do n
mamy do nich dostęp przez podanie nazwy tablicy i indeksu
@a = (2, 3, 4, 5);
$b = $a[0]; -> $b = 2;
$a[0] = 7; -> @a = (7, 3, 4, 5);
$a[1]++;
($a[0], $a[1]) = ($a[1], $a[0]); # zamiana wartości elementów
@[0, 1] = @[1, 0]; # to samo co powyżej
@[0, 1, 2] = @[1, 1, 1];
@kto = (qw(ala ela janek)) [1, 2]; to samo co:
@x = qw(ala ela janek); @kto = @x[1, 2];
$z =1;
$kto[$z + 1];
@a = (7, 8, 9);
@b = (2, 1 ,0);
@c = @a[@b]; -> @c = ($a[2], $a[1], $a[0]); -> @c = (9, 8, 7);
@x = (1, 2, 3);
@x[5] = "ala"; -> @x = (1, 2, 3, undef, undef, "ala");
$#x podaje indeks ostatniego elementu tablicy
podanie ujemnego indeksu powoduje odliczanie elementów od końca
print $x[-1]; -> ala
print $#x; -> 5
print $x[$#x]; -> ala
Funkcje operujące na tablicach
push(@a, $nowa_wartość); # dodanie do tablicy nowego
elementu z prawej strony
$x = pop(@a); # pobranie (usunięcie) ostatniego elementu
tablicy
unshift(@a, $nowa_wartość); # dodanie do tablicy nowego
elementu z lewej strony
$x = shift(@a); # pobranie (usunięcie) pierwszego elementu
tablicy
@b = reverse(@a); # odwrócenie kolejności
@a = sort("zosia", "ala", "janek");
@a = sort(1, 2, 3,13, 22, 21); -> @a = (1, 13, 2, 21, 22, 3);
@a = chomp("zosia\n", "ala\n", "janek\n"); # usuwa ostatni
znak nowej linii z każdego elementu tablicy.
@a = <STDIN>; # wczytanie kolejnych wierszy jako
elementów tablicy a
Struktury kontrolne
bloki instrukcji
{
instrukcja_1;
instrukcja_2;
......................
instrukcja_n;
}
if (warunek) / unless(warunek)
{
instrukcje_1;
}
else / elsif
{
instrukcje_2;
}
while (warunek) / until(warunek)
{
instrukcje;
}
do
{
instrukcje;
} while (warunek);
for (wyr. pocz. ; warunek; zmian wyr.)
{
instrukcje;
}
foreach $i ( @lista )
{
instrukcje;
}
@a = (1, 2, 3, 4, 5);
foreach $i (reverse @a)
{
print $i;
}
@a = (1, 2, 3, 4, 5);
foreach (reverse @a)
{
print $_;
}
@a = (1, 2 .. 7);
foreach ( @a )
{
print $_;
}
@a = (1, 2, 3, 4, 5);
foreach $i ( @a)
{
$i += 2;
}
Tablice asocjacyjne
%a # określenie tablicy asocjacyjnej
$a{$klucz} # element tablicy asocjacyjnej
$a{"ab"} = "ala"; # przypisanie wartości elementowi
%a = ("ab", "ala", "cd", "ela"); # przypisanie tablicy asocjacyjnej listy
%b = %a; # kopiowanie tablicy
%c = reverse %a; # zamiana kluczy z wartościami
Funkcje operujące na tablicach asocjacyjnych
keys(%a) # zwraca listę wszystkich kluczy
foreach $klucz ( keys(%a) )
{
print $klucz, $a{$klucz};
}
values(%a) # zwraca listę wszystkich wartości
$miejsce{"sucha"} = "beskidzka";
$miejsce{"kazimierz"} = "dolny";
@miejsca = values ( %miejsce );
each(%a) # zwraca parę klucz/wartość jako dwuelem. listę
while ( ($x, $y) ) = each (%miejsce) )
{
print $x, $y;
}
delete $a{klucz} # usuwa element tablicy (klucz/wartość)
Operacje wejścia-wyjścia
$a = <STDIN>; # wczytaj kolejny wiersz
@a = <STDIN>; # wczytaj listę
while (defined ( $wiersz = <STDIN> ) )
{
polecenia
}
while ( ( <STDIN> ) )
# to samo co while ( defined($_ = <STDIN> ) )
{
chomp; # to samo co chomp ( $_ )
polecenia
}
while ( ( < > ) )
{
print $_;
}
program # wczytuje i wypisuje ze standardowego wejścia
program plik1 plik2 plik3 # wczytuje i wypisuje wszystkie
wiersze z kolejnych plikow
lub
@ARGV = ("plik1", "plik2", "plik3"); # argumenty programu
while ( ( < > ) )
{
print $_;
}
Wyrażenia regularne
wyrażenie regularne (RE) jest ujęte w ukośniki:
/RE/ # /a.*b[^1-9]*/
while (< >)
{
if ( /RE/ )
{
print $_;
}
}
wyrażenie może zawierać znaki specjalne (interpretowane):
\ . ^ $ * + ? { } ( ) |
oznaczenie |
klasa znaków |
negacja |
klasa znaków |
\d (cyfra) |
[0-9] |
\D (nie cyfra) |
[^0-9] |
\w (wyraz) |
[a-zA-Z0-9] |
\W (nie wyraz) |
[^a-zA-Z0-9] |
\s (odstęp) |
[ \r\t\n\f] |
\S (nie odstęp) |
[^ \r\t\n\f] |
znak* # zero lub dowolnie wiele wystąpień znaku
znak+ # jedno lub dowolnie wiele wystąpień znaku
znak? # zero lub jedno wystąpienie znaku
znak{m,n} # m do n wystąpień znaku
znak{m,} # m lub dowolnie wiele wystąpień znaku
znak{0,n} # 0 do n wystąpień znaku
znak{m} # dokładnie m wystąpień znaku
Wyrażenia regularne
$z = "ala ma kota";
wzorzec: /.*a/ # odpowiada mu "ala ma kota" (najdłuższy ciąg)
wzorzec: /.*a?/ # odpowiada mu "a" (najkrótszy ciąg)
/a(.)b\1/ # \1 powtarza część wzorca w nawiasach ( )
# /aXbX/ /aYbY/
/a.b./ # inny wzorzec, np /aXbY/ /aYbX/
/a(.)b(.)c\2d\1/ # \2 i \1 powtarzają części wzorców w naw. ( )
# /aXbYcYdX/ /aYbXcXdY/
/a(.*)b\1c/ # /aXYXbXYXc/
wyrażenia \1 \2 .. nazywany referencjami; możemy ich używać
przy wyszukiwanie tekstu (do powtórzeń) i do zamiany tekstu
można ich także używać w dalszej części programu (aż do podania
nowych referencji), przy użyciu znaku $: $1, $2, ...
/RE1|RE2|....|REn/ # jedno z wyrażeń RE
Zakotwiczenia
^ na początku napisu lub po znaku nowej linii
$ na końcu napisu lub przed znakiem nowej linii
\b na granicy wyrazu
\B na granicy nie-wyrazu
\A na początku napisu
\Z na końcu napisu lub przed znakiem nowej linii na końcu
napisu
\z na końcu napisu
Operacje na wyrażeniach regularnych
dopasowanie wzorca:
$a =~ m/RE/modyfikator # zwraca true lub false
zamiana wzorca:
$a =~ s/RE/tekst/ modyfikator # zamienia RE na tekst
+modyfikatory:
i # ignoruje wielkość liter
g # wyszukuje wszystkie wystąpienia RE
zamiana znaków:
$a =~ tr/zbiór_1/zbiór_2/ # każdy znak ze zbioru_1 jest
zamieniany na odpowiadający mu znak ze zbioru_2
$a =~ tr/zbiór_1/zbiór_2/c # każdy znak spoza zbioru_1 jest
zamieniany na odpowiadający mu znak ze zbioru_2
jeżeli zbiór_2 jest krótszy od zbioru_1 to ostatni znak w zbiorze_2 podany jest powtarzany tyle razy, żeby długości zbiorów były jednakowe
$a =~ tr/zbiór//d # usuwa każdy znak ze zbioru
$a =~ tr/zbiór//cd # usuwa każdy znak spoza zbioru
$a =~ tr/zbiór//s # usuwa każdy powtarzany znak ze zbioru
$a =~ tr/zbiór//cs # usuwa każdy powtarz. znak spoza zbioru
Funkcje split i join
split wyszukuje wszystkie wystąpienia RE w napisie
fragmenty napisu, niepasujące do wzorca są zwracane jako lista
$wiersz = "jan::101:501:Jan:/home/jan:/usr/bin/bash";
@pola = split (/:/, $wiersz);
tablica @pola to: ("jan","","101","501","Jan","/home/jan","/usr/bin/bash")
@pola = split (/:+/, $wiersz);
tablica @pola to: ("jan","101","501","Jan","/home/jan","/usr/bin/bash")
$_ = "napis";
@wyrazy = split (/RE/); # to samo co @wyrazy = split (/RE/, $_);
join pobiera listę wartości i łączy je, oddzielając podanym napisem
$wiersz_pswd = join (":", @pola);
Funkcje
definicja funkcji, umieszczona w dowolnym miejscu programu:
sub nazwa_funkcji
{
polecenie_1;
polecenie_2;
.....................
polecenie_n;
}
sub ala
{
print "ala ma kota\n";
}
funkcję wywołuje się przez podanie jej nazwy
funkcja zwraca wartość przez return
sub suma
{
return $a + $b;
}
$x = suma( );
sub lista
{
return ($a, $b);
}
@x = lista( );
Argumenty funkcji
lista podanych do funkcji argumentów jest przechowywana w specjalnej zmiennej @_
sub fun1
{
print "pierwszy argument, $_[0] \n";
}
$x = "ala";
fun1($x);
fun1("zuzanna");
sub suma2
{
return $_[0] + $_[1];
}
$x = suma2(7, 1);
sub suman
{
$suma = 0;
foreach $_ ( @_ ) {
$suma += $_;
}
return $suma;
}
$x = suman(7, 1, 2, 8);
$x = suman(2 .. 13);
Zasięg zmiennych
typy zmiennych;
global # dostępne wszędzie
my # dostępne tylko w bieżącej funkcji
local # dostępne w tylko w bieżącej funkcji i wywoływanych
przez nią funkcjach
#! /usr/bin/perl
sub f3()
{
print "f3\n";
print "g w f3: ", $g , "\n";
print "m w f3: ", $m , "\n";
print "l w f3: ", $l , "\n";
}
sub f1()
{
$g = "globf1";
my $m = "myf1";
local $l = "localf1";
f3;
}
sub f2()
{
print "g w f2: ", $g , "\n";
print "m w f2: ", $m , "\n";
print "l w f2: ", $l , "\n";
}
f1;
f2;
print "g w main: " ,$g , "\n";
print "m w main: " ,$m , "\n";
print "l w main: " ,$l , "\n";
exit
Inne struktury sterujące
last:
while (warunek_1)
{
polecenia_1;
if (warunek_2)
{
polecenia_2;
last; # opuść pętlę
}
polecenia_3;
}
polecenia_4; # przechodzimy do tego miejsca
next:
while (warunek_1)
{
polecenia_1;
if (warunek_2)
{
polecenia_2;
next; # zakończ pętlę
}
polecenia_3;
# przechodzimy do tego miejsca
}
polecenia_4;
redo:
while (warunek_1)
{
# przechodzimy do tego miejsca
polecenia_1;
if (warunek_2)
{
polecenia_2;
redo; # przeskocz do początku pętli
}
polecenia_3;
}
polecenia_4;
etykiety:
ZEWN: for ($i = 1; $i < 10; $i++) {
WEWN: for ($j = 1; $j < 10; $j++) {
if ( warunek_1 )
{
last ZEWN;
}
if ( warunek_2 )
{
last WEWN;
}
}
}
wyrażenie [ if | unless | while | until ] warunek
$n = 10; $i = 1;
$i += 1 until $i > $n;
wyrażenie_1 && wyrażenie_2
wyrażenie_1 || wyrażenie_2
Pliki
standardowe deskryptory plików:
<STDIN> <STDOUT> <STDERR>
print <STDOUT> "tekst" # to samo co print "tekst";
$z = <STDIN>;
otwieranie plików:
open NAZWA, "tryb nazwa_pliku";
tryby:
< lub brak # odczyt
> # zapis
>> # dopisanie
+< # odczyt/zapis
+> # odczyt/zapis, usunięcie starej zawartości
read ( NAZWA, $z, l. bajtów);
write NAZWA ; # zapis zgodnie z wybranym formatem
select NAZWA; # ustawia domyślne wyjście
write; # zapis na domyślne wyjscie
Formaty
definicja formatu:
format nazwa_formatu =
wiersz pól_1
wiersz znaków_1
wiersz pól_2
wiersz znaków_2
.............................
wiersz pól_n
wiersz znaków_n
.
format ZAROBKI =
@<<<<<<<<< @<<<<<<<<<
$nazwisko $zarobki
.
w wierszu pól każde pole rozpoczyna się znakiem @
w polu mogą być następujące znaki:
< wyrównanie do lewej
> wyrównanie do prawej
| wyrównanie do środka
# format liczbowy
$~ = nazwa_formatu; # ustawia format domyślny