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