Perl - Wyrażenia regularne

Transkrypt

Perl - Wyrażenia regularne
Wyrażenia regularne w Perlu
Narzędzia informatyczne w językoznawstwie
Perl - Wyrażenia regularne
I
Na ostatnich zajęciach zapoznaliśmy się z Wyrażeniami
Regularnymi na sucho, dziś omówimy ich integrację w Perlu.
I
Na wykładzie dotyczącym haszów poznaliśmy jedno z
najpotężniejszych narzędzi Perla, drugim (lub pierwszym?)
najważniejszym mechanizmem tego języka są właśnie RE
(Regular Expressions, będziemy stosowali taki skrót)
I
RE same w sobie nie są może szczególnie potężne, ale w
połączeniu z językiem programowania, można wykorzystać je
do wielu różnych zadań
I
Wyrażenia regularne w Perlu ustanowiły pewien standard:
PCRE (Perl Compatible Regular Expressions)
I
Większość szanujących się programów korzysta właśnie z tego
standardu, inne standardy RE są raczej egzotyczne
Marcin Junczys-Dowmunt
[email protected]
Zakład Logiki Stosowanej
http://www.logic.amu.edu.pl
16. styczeń 2008
Marcin Junczys-Dowmunt
Narzędzia informatyczne w językoznawstwie
Pierwsze przykłady
1
print " Dopasowano \ n " if ( " Hello World " =~ / World /);
$reg = ’ World ’;
print " Dopasowano \ n " if ( " Hello World " =~ / $reg /);
I
RE otaczamy w Perlu operatorami /.../
I
Porównując zmienną lub łańcuch z RE korzystamy z
operatorów =~ (dopasowanie pozytywne) lub !~ (dopasowanie
negatywne)
I
Wewnątrz operatorów /.../ działa interpolacja zmiennych,
trzeba pamiętać o związku cudzysłowu podwójnego ze
znakiem \
Marcin Junczys-Dowmunt
Narzędzia informatyczne w językoznawstwie
2/20
Przykład bardziej sensowny – perlowy minigrep.pl
print " Nie dopasowano \ n " if ( " Hello World " !~ / World /);
5
Marcin Junczys-Dowmunt
1/20
Narzędzia informatyczne w językoznawstwie
3/20
1
my $regexp = shift @ARGV ;
while ( < >) {
print if (/ $regexp /);
}
I
Unixowy Grep to program, który wyświetla wiersze (i inne
informacje) z pliku lub z plików tekstowych, które pasują do
podanego wzorca, np.
grep "\b[Aa]dam\b" plik1.txt
I
Nasz prosty program perlowy minigrep.pl działa podobnie,
np. perl minigrep.pl "\b[Aa]dam\b" plik1.txt
Z tym, że nie informuje o nazwie pliku lub numerze wiersza
(patrz zadanie domowe)
I
Jak widać użycie samego operatora /.../ powoduje
porównywanie ze zmienną standardową
Marcin Junczys-Dowmunt
Narzędzia informatyczne w językoznawstwie
4/20
Sortowanie mieszane raz jeszcze
1
Grupowania i odwołania do grup z poza RE
1
my @mieszane = (4 , " Antek " ,13 ,9 , " Zenon " ,2 ,10 , " Mirek " );
print join ( " ," , sort {
is_num ( $a ) && is_num ( $b ) ? $a <= > $b : $a cmp $b ;
} @mieszane ). " \ n " ;
5
sub is_num {
my $test = shift ;
return $test =~ /^[+ -]?\ d +(\.\ d +)?([ eE ][+ -]?\ d +)? $ /;
}
I
Nie potrafiliśmy sortować alfabetycznie z liczbami
poprzedzającymi łańcuchy znakowe w porządku rosnącym
I
Teraz potrafimy
I
Funkcja is num sprawdza, czy dany łańcuch znakowy ma
postać liczby
Marcin Junczys-Dowmunt
Narzędzia informatyczne w językoznawstwie
1
I
I
Wewnątrz RE korzystamy z odwołań typu \1, w programach
ze zmiennych typu $1
I
Dopasowanie w użyte w kontekście listowym powoduje
przypisanie kolejnych grup do kolejnych elementów listy.
my $record = " Jan Kowalski , 20.12.1982 " ;
my @gr = $record =~ /^(\ w +)\ s (\ w +) ,\ s ([\ w .]+) $ /;
print " $gr [1] , $gr [0] urodzil ( a ) sie dnia $gr [2]\ n " ;
Narzędzia informatyczne w językoznawstwie
my $record = " Jan Kowalski , Joanna Nowak " ;
$record =~ /^((? < imie >\ w +) (? < nazwisko >\ w +)( , )?)+ $ /;
print " $ +{ nazwisko } , $ +{ imie }\ n " ;
I
18. grudnia 2007 pojawił się nowy Perl o numerze 5.10.0
Standardowo każda para nawiasów generuje nową grupę
(grupy numerujemy według nawiasów otwierających,
niezależnie od głębokości zagnieżdżeń)
I
Od tej wersji działają tzw. grupy nazwane
I
Grupę nazwaną tworzymy za pomocą konstrukcji
(?<nazwa>...) lub (?’nazwa’...)
Gdy korzystamy z kwantyfikatorów może to być działaniem
niepożądanym
I
Wewnątrz RE odwołujemy się do nich przez \gnazwa
I
W programie odwołujemy się do nich przez specjalny hasz %+,
np. $+{nazwa};
I
Nazwy mogą się powtarzać, ale możemy się odwołać tylko do
ostatniego dopasowania
Wtedy korzystamy z nawiasów niegrupujących (?:...)
Marcin Junczys-Dowmunt
6/20
Grupy nazwane
my $number = " nasza liczba : -3.1105 e -010 " ;
$number =~ /([+ -]?\ d +(?:\.\ d +)?(?:[ eE ]([+ -]?\ d +))?)/;
print " Liczba $1 ma wykładnik $2 \ n " ;
I
Zmienne specjalne $1 do $9 odwołują się odpowiednio do
grup \1 do \9, jeśli takie grupy nie zostały dopasowane to
zmienne zawierają undef
Marcin Junczys-Dowmunt
1
I
I
5/20
Nawiasy niegrupujące
1
my $record = " Jan Kowalski , 20.12.1982 " ;
$record =~ /^(\ w +)\ s (\ w +) ,\ s ([\ w .]+) $ /;
print " $2 , $1 urodzil ( a ) sie dnia $3 \ n " ;
Narzędzia informatyczne w językoznawstwie
7/20
Marcin Junczys-Dowmunt
Narzędzia informatyczne w językoznawstwie
8/20
Funkcja split - dzielenie rekordów i nie tylko
1
1
Program tworzący listę frekwencynją raz jeszcze
my $rec = " Kowalski Jan 20 -12 -1984\ n " ;
my ( $nazw , $imie , @data ) = split (/\ s +|\ -/ , $rec );
print " $imie $nazw urodzil sie w roku $data [2]\ n " ;
I
Funkcja split jest jedną z bardziej przydatnych funkcji w
Perlu, łącząca w sobie funkcjonalność RE i list
(przeciwieństwo funkcji join)
I
Dzieli dany łańcuch znakowy na pola według podanego RE
I
Jeśli podane RE nie zawiera nawisów, to części dopasowane
nie znajdą się w liście wynikowej
I
Jeśli RE zawiera nawiasy grupujące, to dopasowane grupy
znajdują się w listach pomiędzy polami
5
10
Narzędzia informatyczne w językoznawstwie
my % freq ;
while ( < >) {
my @tokens = split (/[\ s . ,;?!:\ -()]+/ , $_ );
foreach my $token ( @tokens ) {
$freq { $token }++;
}
}
foreach my $token ( sort keys % freq ) {
print " $token $freq { $token }\ n " ;
}
I
I
my $rec = " Kowalski Jan 20 -12 -1984\ n " ;
my ( $nazw , $imie , @data ) = split (/\ s +|(\ -)/ , $rec );
print join ( " : " , @data ). " \ n " ;
Marcin Junczys-Dowmunt
I
W końcu znamy wszystkie narzędzia potrzebne do napisania
programu zliczającego liczbę wystąpień wyrazów w tekście
Korzystamy tutaj prawie ze wszystkich mechanizmów
poznanych na wcześniejszych wykładach
W jakim porządku jest wyświetlana lista frekwencyjna? Jaki
porządek byłby bardziej przydatny?
Marcin Junczys-Dowmunt
9/20
Flagi
1
1
Narzędzia informatyczne w językoznawstwie
10/20
Flaga i – (case) insensitive
1
my $tekst = " dZiWnA pIsOwNiA "
5
if ( $tekst =~ / pisownia / i ) {
print " Dopasowanie sie powiodlo \ n " ;
}
$zmienne =~ / wzorzec / msigx
I
Zachowywanie domyślne RE możemy modyfikować za pomocą
tzw. flag
I
Flagi mają postać pojedynczych liter umieszczanych
bezpośrednio za operatorami RE /.../
I
Flagi można ze sobą łączyć, przy czym niektóre kombinacje są
szczególnie pożyteczne
Marcin Junczys-Dowmunt
Narzędzia informatyczne w językoznawstwie
11/20
I
Flaga i włącza tryb dopasowywania bez rozróżniania wielkości
liter
I
Flagę i należy stosować oszczędnie, ponieważ spowalnia
proces dopasowywania RE
I
Jeśli istnieje taka możliwość, to lepiej korzystać np. z
odpowiednich klas znaków (np. gdy dopuszczalne są duże i
małe litery na początku wyrazu)
Marcin Junczys-Dowmunt
Narzędzia informatyczne w językoznawstwie
12/20
Flaga g – global
1
5
Zastępowanie
my $tekst = " The Messenger spacecraft dashed past
Mercury today " ;
1
my @tokens = $tekst =~ /([\ w \ -]+)/ g ;
print " $_ \ n " foreach ( @tokens );
I
Domyślnie RE dopasują pierwsze możliwe wystąpienie
szukanego wzorca i tylko pierwsze wystąpienie
I
Flaga g powoduje, że dopasowane zostaną wszystkie pasujące
wystąpienia wzorca
I
I
5
Gdy jedno wystąpienie zostanie dopasowane, następne
wystąpienie zostanie dopasowane dopiero za końcem
poprzedniego dopasowania
Jeśli w takim RE wykorzystamy nawiasy grupujące, najłatwiej
odwołać się do grup poprzez tablicę
Marcin Junczys-Dowmunt
Narzędzia informatyczne w językoznawstwie
Operator zastępowania s/.../.../ składa się dwóch części:
I
W pierwszym polu znajduje się dowolne wyrażenie regularne
I
W drugim polu znajduje się dowolny łańcuch znakowy
(działający jak podwójnym cudzysłowu), a nie wyrażenie
regularne
I
Korzystamy ze zmiennych typu $1 a nie z odwołań typu \1
Marcin Junczys-Dowmunt
Narzędzia informatyczne w językoznawstwie
1
Większość flag działa również w połączeniu z operatorem
zastępowania
my $normalizacja = " miłośnik żab " ;
$normalizacja =~ tr / ąćęłńóśżź / acelnoszz /;
print $normalizacja . " \ n " ;
I
Transliteracja z operatorem tr/.../.../ często pojawia się
w rozdziałach dotyczących RE, jednak tak naprawdę nie działa
jak RE
I
Flaga g spowoduje zastąpienie wszystkich dopasowań w
łańcuchu, nie tylko pierwszego
I
Flaga e pozwala na wpisywanie kodu Perla do drugiego pola
zastępowania.
I
Pola operatora zawierają klasy znaków
I
Tak naprawdę flaga e otacza drugie pole funkcją eval(),
która wykonuje kod Perla zapisany w łańcuchu znakowym
Każdy znak z pierwszego pola jest zastępowany znakiem na
tej samej pozycji w klasie znaków z drugiego pola
I
Gdy drugie pole zawiera mniej znaków niż pierwsze, to ostatni
znak z drugiego pola dopełnia różnicę
I
Marcin Junczys-Dowmunt
Narzędzia informatyczne w językoznawstwie
14/20
Transliteracja
$tekst =~ s /([+ -]?\ d +(?:\.\ d +)?)/ log ( $1 )/ eg ;
I
I
13/20
Zastępowanie globalne oraz ewaluacja
1
$_ = " green scaly dinosaur " ;
s /(\ w +) (\ w +)/ $2 , $1 /; # scaly , green dinosaur
s /^/ huge , /;
# huge , scaly , green dinosaur
s / ,.* een //;
# huge dinosaur
s / green / red /;
# huge dinosaur
s /\ w + $ /( $ ‘!) $ &/;
# huge ( huge !) dinosaur
s /\ s +(!\ W +)/ $1 /;
# huge ( huge !) dinosaur
s / huge / gigantic /;
# gigantic ( huge !) dinosaur
15/20
Marcin Junczys-Dowmunt
Narzędzia informatyczne w językoznawstwie
16/20
Zachowanie kropki a flagi s i m
I
Zachowanie standardowe. ’.’ dopasuje wszystkie znaki oprócz
”\n” . ^ dopasuje tylko początek łańcucha, a $ tylko koniec
łańcuchy lub przed ”\n” na końcu łańcucha
I
Flaga s: Traktuje łańcuch znakowy jak jedną długą linię. ’.’
dopasuje wszystkie znaki, łącznie z ”\n” . ^ dopasuje tylko
początek łańcucha, a $ tylko koniec łańcuchy lub przed ”\n”
na końcu łańcucha
I
I
Flaga o – Kompilacja wzorców
1
5
Flaga m: Traktuje łańcuch znakowy jak zbiór wierszy. ’.’
dopasuje wszystkie znaki oprócz ”\n” . ^ i $ mogą dopasować
początek i koniec każdego z wierszy.
Flagi s i m: Traktuje łańcuch znakowy jak jedną długą linię,
ale wykrywa obecność wielu wierszy. ’.’ dopasuje wszystkie
znaki, łącznie z ”\n” . ^ i $ mogą dopasować początek i
koniec każdego z wierszy.
Marcin Junczys-Dowmunt
Narzędzia informatyczne w językoznawstwie
5
10
I
Flaga o kompiluje nasze RE, tzn. że RE jest optymalizowane i
staje się niezmienne (!)
I
Optymalizację warto stosować, gdy wewnątrz RE odbywa się
interpolacja zmiennych
I
Proces dopasowywania przyspieszy wtedy znacznie
I
Uwaga: Międzyczasowe zmiany zmiennej interpolowanej nie
zmienią wzorca, będzie on miał postać, którą miał przy
pierwszej kompilacji
Marcin Junczys-Dowmunt
Narzędzia informatyczne w językoznawstwie
18/20
Podsumowanie
my $number = " nasza liczba : -3.1105 e -010 " ;
$number =~ /
(
[+ -]?
# opcjonalny znak
\d+
# część całkowita mantysy
(?:\.\ d +)?
# opjconalna część ułamkowa mantysy
(?:
[ eE ]
([+ -]?\ d +) # wykładnik z opcjonalnym znakiem
)?
# wykładnik też jest opcjonalny
)
/x;
print " Liczba $1 ma wykładnik $2 \ n " ;
I
Flaga x pozwala na bardziej czytelny zapis RE
I
Białe znaki oraz komentarze są ignorowane
I
Jeśli chcemy dopasować spacje lub # korzystamy z \ oraz \#
Marcin Junczys-Dowmunt
if ( " 16. stycznia 2008 " =~ /\ d \ d \. $pat \ d {4}/ o ) {
print " Dopasowano \ n " ;
}
17/20
Flaga x – extended RE
1
my @miesiace = qw ( stycznia lutego marca ...);
my $pat = join ( " | " , @miesiace );
Narzędzia informatyczne w językoznawstwie
19/20
I
Poznaliśmy kilka podstawowych własności Wyrażeń
Regularnych używanych w Perlu
I
Jest jeszcze wiele własności, flag, znaków specjalnych, których
jeszcze nie umówiliśmy: np. tzw. Look-Ahead
I
Zachęcam bardzo do przeczytania innych źródeł, np. oficjalnej
dokumentacji do Wyrażeń Regularnych w Perlu. Linki
znajdują się na stronie przedmiotu
Marcin Junczys-Dowmunt
Narzędzia informatyczne w językoznawstwie
20/20