Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00574 009608 17345314 na godz. na dobę w sumie
Wyrażenia regularne - książka
Wyrażenia regularne - książka
Autor: Liczba stron: 320
Wydawca: Helion Język publikacji: polski
ISBN: 83-7197-351-9 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> programowanie >> techniki programowania
Porównaj ceny (książka, ebook (-25%), audiobook).
Wyrażenia regularne to niezwykle skuteczny mechanizm przetwarzania tekstów i innych danych. Ci, którzy do tej pory nie zetknęli się z tym pojęciem, odkryją dzięki tej książce nowe, potężne narzędzia, pozwalające w pełni zapanować nad danymi. Prezentowana tu wiedza jest tak szczegółowa i obszerna, że nawet komputerowi weterani znajdą coś nowego dla siebie.

Umiejętne stosowanie wyrażeń regularnych pozwala radykalnie uprościć przetwarzanie wszelkiego rodzaju informacji, poczynając od poczty elektronicznej, poprzez pliki dzienników aż do dokumentów tekstowych. Mechanizm ten odgrywa niezwykle ważną rolę w programowaniu skryptów CGI, często przetwarzających rozmaite dane tekstowe.

Wyrażenia regularne nie funkcjonują samodzielnie. Oprócz doskonale wszystkim znanego programu grep, wchodzą one w skład takich narzędzi programisty, jak:

Korzystanie z wyrażeń regularnych wymaga nie tylko wiedzy teoretycznej, ale również znajomości pewnych niuansów. Jeffrey Friedl konsekwentnie prowadzi nas przez kolejne etapy tworzenia konstrukcji, które dokładnie zrealizują wszystkie postawione przed nimi zadania.

Wyrażenia regularne nie istnieją oczywiście same dla siebie. Na stronach książki przedstawiono liczne przykłady wykorzystujących je narzędzi, a także wiele praktycznych przykładów. Szczególnie dużo uwagi poświęcono językowi Perl, wyposażonemu w bogaty zestaw funkcji przeznaczonych specjalnie do obsługi wyrażeń regularnych.

Zawarte w tej książce porady pozwolą Czytelnikom uniknąć wszelkich pułapek i skutecznie wykorzystać możliwości wyrażeń regularnych.

'Książka była dla mnie tyleż przyjemna, co pouczająca, nawet w kwestiach związanych z Perlem'
Tom Christiansen, współautor książki Perl. Programowanie

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

IDZ DO IDZ DO PRZYK£ADOWY ROZDZIA£ PRZYK£ADOWY ROZDZIA£ SPIS TRE(cid:140)CI SPIS TRE(cid:140)CI KATALOG KSI¥flEK KATALOG KSI¥flEK KATALOG ONLINE KATALOG ONLINE ZAM(cid:211)W DRUKOWANY KATALOG ZAM(cid:211)W DRUKOWANY KATALOG TW(cid:211)J KOSZYK TW(cid:211)J KOSZYK DODAJ DO KOSZYKA DODAJ DO KOSZYKA CENNIK I INFORMACJE CENNIK I INFORMACJE ZAM(cid:211)W INFORMACJE ZAM(cid:211)W INFORMACJE O NOWO(cid:140)CIACH O NOWO(cid:140)CIACH ZAM(cid:211)W CENNIK ZAM(cid:211)W CENNIK CZYTELNIA CZYTELNIA FRAGMENTY KSI¥flEK ONLINE FRAGMENTY KSI¥flEK ONLINE Wydawnictwo Helion ul. Chopina 6 44-100 Gliwice tel. (32)230-98-63 e-mail: helion@helion.pl Wyra¿enia regularne Autor: Jeffrey E. F. Friedl T‡umaczenie: Adam Podstawczyæski ISBN: 83-7197-351-9 Tytu‡ orygina‡u: Format: B5, stron: 320 Mastering Regular Expressions Wyra¿enia regularne to niezwykle skuteczny mechanizm przetwarzania tekst(cid:243)w i(cid:160) innych danych. Ci, kt(cid:243)rzy do tej pory nie zetknŒli siŒ z tym pojŒciem, odkryj„ dziŒki tej ksi„¿ce nowe, potŒ¿ne narzŒdzia, pozwalaj„ce w pe‡ni zapanowa(cid:230) nad danymi. Prezentowana tu wiedza jest tak szczeg(cid:243)‡owa i obszerna, ¿e nawet komputerowi weterani znajd„ co(cid:156) nowego dla siebie. UmiejŒtne stosowanie wyra¿eæ regularnych pozwala radykalnie upro(cid:156)ci(cid:230) przetwarzanie wszelkiego rodzaju informacji, poczynaj„c od poczty elektronicznej, poprzez pliki dziennik(cid:243)w a¿ do dokument(cid:243)w tekstowych. Mechanizm ten odgrywa niezwykle wa¿n„ rolŒ w programowaniu skrypt(cid:243)w CGI, czŒsto przetwarzaj„cych rozmaite dane tekstowe. Wyra¿enia regularne nie funkcjonuj„ samodzielnie. Opr(cid:243)cz doskonale wszystkim znanego programu grep, wchodz„ one w sk‡ad takich narzŒdzi programisty, jak: translatory jŒzyk(cid:243)w skryptowych (m.in. Perl, Tcl, awk i Python), edytory tekst(cid:243)w (Emacs, vi, Nisus Writer i inne), (cid:156)rodowiska programowania (m.in. Delphi i Visual C++) inne wyspecjalizowane narzŒdzia (np. lex, Expert czy sed). Korzystanie z wyra¿eæ regularnych wymaga nie tylko wiedzy teoretycznej, ale r(cid:243)wnie¿ znajomo(cid:156)ci pewnych niuans(cid:243)w. Jeffrey Friedl konsekwentnie prowadzi nas przez kolejne etapy tworzenia konstrukcji, kt(cid:243)re dok‡adnie zrealizuj„ wszystkie postawione przed nimi zadania. Wyra¿enia regularne nie istniej„ oczywi(cid:156)cie same dla siebie. Na stronach ksi„¿ki przedstawiono liczne przyk‡ady wykorzystuj„cych je narzŒdzi, a tak¿e wiele praktycznych przyk‡ad(cid:243)w. Szczeg(cid:243)lnie du¿o uwagi po(cid:156)wiŒcono jŒzykowi Perl, wyposa¿onemu w bogaty zestaw funkcji przeznaczonych specjalnie do obs‡ugi wyra¿eæ regularnych. Zawarte w tej ksi„¿ce porady pozwol„ Czytelnikom unikn„(cid:230) wszelkich pu‡apek i(cid:160) skutecznie wykorzysta(cid:230) mo¿liwo(cid:156)ci wyra¿eæ regularnych. (cid:132)Ksi„¿ka by‡a dla mnie tyle¿ przyjemna, co pouczaj„ca, nawet w kwestiach zwi„zanych z Perlem(cid:148) Tom Christiansen, wsp(cid:243)‡autor ksi„¿ki Perl. Programowanie 6/.3;+   463;+./2/.3;6+ /q6/19+62-  Rozwiązywanie prawdziwych problemów...................................................e........................... 18 Wyrażenia regularne jako język ...................................................e........................................... 19 Analogia do nazw plików...................................................e............................................. 19 Analogia do języka...................................................e...................................................e.... 20 Myślenie wyrażeniami regularnymi ...................................................e..................................... 21 Przeszukiwanie plików tekstowych — egrep ...................................................e.............. 22 Metaznaki programu egrep ...................................................e...................................................e 23 Początek i koniec wiersza ...................................................e............................................ 23 Klasy znaków ...................................................e...................................................e............ 23 Kropka, czyli dowolny znak ...................................................e........................................ 26 Alternacja ...................................................e...................................................e.................. 27 Granice słów...................................................e...................................................e.............. 28 W skrócie...................................................e...................................................e................... 29 Elementy opcjonalne...................................................e...................................................e. 30 Inne kwantyfikatory — powtarzanie...................................................e............................ 31 Ignorowanie wielkości znaków...................................................e.................................... 33 Nawiasy i odwołania wsteczne ...................................................e.................................... 33 Szybki unik...................................................e...................................................e................ 35 Ponad podstawy ...................................................e...................................................e................. 35 Różnorodność językowa ...................................................e.............................................. 35 Cel tworzenia wyrażenia regularnego...................................................e.......................... 35 Jeszcze kilka przykładów...................................................e............................................. 36 Terminologia wyrażeń regularnych ...................................................e............................. 38 Podwyższanie kwalifikacji...................................................e........................................... 40 Podsumowanie ...................................................e...................................................e.......... 42 Uwagi osobiste...................................................e...................................................e................... 43  6/.3;+   6o+.;6+ /q6/19+62-  O przykładach ...................................................e...................................................e.................... 45 Perl — krótkie wprowadzenie...................................................e...................................... 46 Wyszukiwanie tekstu za pomocą wyrażeń regularnych...................................................e....... 48 Przykład bliższy rzeczywistości...................................................e................................... 49 Skutki uboczne udanego dopasowania ...................................................e........................ 50 Przeplatanie wyrażeń regularnych ...................................................e............................... 53 Chwila odpoczynku...................................................e...................................................e... 56 Modyfikowanie znalezionego tekstu ...................................................e.................................... 57 Edycja zautomatyzowana...................................................e............................................. 60 Proste przetwarzanie wiadomości e-mailowych ...................................................e.......... 61 I znów powtarzające się słowa...................................................e..................................... 66   6/1.092-3.+2;6+ /q6/19+62-  Spacerkiem po krainie wyrażeń regularnych...................................................e........................ 72 Świat według grepa ...................................................e...................................................e... 72 Czas wszystko zmienia ...................................................e................................................ 73 Najkrótszy przegląd ...................................................e...................................................e........... 74 POSIX ...................................................e...................................................e....................... 76 „Otoczka” wyrażeń regularnych...................................................e........................................... 77 Identyfikacja wyrażenia regularnego ...................................................e........................... 78 Operacje na dopasowanym tekście ...................................................e.............................. 78 Inne przykłady...................................................e...................................................e...........79 „Otoczka” wyrażeń regularnych — podsumowanie...................................................e.... 81 Silniki a błyszczący lakier ...................................................e.................................................... 82 Lakier ...................................................e...................................................e........................ 82 Silnik i kierowca..................................e...................................................e.........................82 Typowe metaznaki...................................................e...................................................e............. 82 Skróty znakowe ...................................................e...................................................e......... 83 Łańcuchy jako wyrażenia regularne...................................................e............................. 86 Skrótowy zapis klas, kropka i klasy znaków ...................................................e............... 88 Zakotwiczanie ...................................................e...................................................e........... 92 Grupowanie i wydobywanie informacji...................................................e....................... 94 Kwantyfikatory...................................................e...................................................e.......... 94 Alternacja ...................................................e...................................................e.................. 95 Przewodnik po dalszych rozdziałach...................................................e.................................... 95 Informacje specyficzne dla konkretnego narzędzia ...................................................e..... 96  /-+2+46/8;+6+2+;6+ /q  Przekręcamy klucz w stacyjce ...................................................e.............................................. 97 Dwa typy silników ...................................................e...................................................e.... 97 Nowe standardy...................................................e...................................................e......... 98 Typy mechanizmów wyrażeń regularnych ...................................................e.................. 98 Kilka dodatkowych pytań ...................................................e.......................................... 100 Podstawy dopasowywania ...................................................e.................................................. 100 O przykładach ...................................................e...................................................e......... 100 Zasada 1. Najwcześniejsze dopasowanie wygrywa...................................................e... 101 6/.3;+  Skrzynia biegów...................................................e...................................................e...... 102 Części silnika...................................................e...................................................e...........102 Zasada 2. Niektóre metaznaki są „zachłanne” ...................................................e........... 103 Sterowanie wyrażeniem a sterowanie tekstem ...................................................e................... 108 Mechanizm NFA — sterowanie wyrażeniem...................................................e............ 108 Mechanizm DFA — sterowanie tekstem ...................................................e................... 109 Wyjaśnienie „zagadki istnienia” ...................................................e................................ 110 Wycofywanie ...................................................e...................................................e................... 111 „Krucha” analogia ...................................................e...................................................e... 111 Dwie istotne sprawy dotyczące wycofywania ...................................................e........... 112 Zachowane stany ...................................................e...................................................e..... 113 Wycofywanie a zachłanność ...................................................e...................................... 114 Więcej o zachłanności ...................................................e...................................................e..... 117 Problemy z zachłannością ...................................................e.......................................... 117 „Cudzysłowy” wieloznakowe ...................................................e.................................... 118 Lenistwo? ...................................................e...................................................e................118 Zachłanność zawsze sprzyja dopasowaniu ...................................................e................ 119 Czy alternacja jest zachłanna? ...................................................e................................... 120 Sposoby wykorzystania alternacji niezachłannej...................................................e....... 121 Alternatywa zachłanna z perspektywy...................................................e....................... 123 Klasy znaków a alternacja...................................................e.......................................... 123 NFA, DFA i POSIX...................................................e...................................................e.........123 „Najdłuższe najbardziej z lewej” ...................................................e............................... 123 POSIX a zasada „najdłuższe najbardziej z lewej” ...................................................e..... 125 Szybkość i wydajność ...................................................e................................................ 126 Porównanie mechanizmów DFA i NFA ...................................................e.................... 126 Techniki tworzenia wyrażeń regularnych...................................................e........................... 128 O czym należy pamiętać ...................................................e............................................ 129 Warto być konkretnym...................................................e............................................... 130 Trudności i niemożliwości ...................................................e......................................... 133 Uwaga na niepożądane dopasowania...................................................e......................... 134 Dopasowanie ograniczonego tekstu...................................................e........................... 136 Wiedza o przetwarzanych danych...................................................e.............................. 139 Dalsze przykłady zachłanności ...................................................e.................................. 139 Podsumowanie...................................................e...................................................e................. 142 Podsumowanie mechaniki dopasowania...................................................e.................... 142 Praktyczne efekty działania mechanizmów dopasowania wzorca................................ 143  346+-3;;+2/;6+ /q6/19+62-  Przykład otrzeźwiający...................................................e...................................................e.... 146 Prosta zmiana — najlepszą chorągiew posyłamy przodem.......................................... 146 Krok dalej: znalezienie źródła zachłanności...................................................e.............. 147 Twarda rzeczywistość ...................................................e................................................ 149 O wycofywaniu ogólnie...................................................e...................................................e... 151 POSIX NFA — więcej pracy...................................................e..................................... 152 Gdy nie ma dopasowania ...................................................e........................................... 152 Dążenie do precyzji...................................................e...................................................e. 153 Alternacja może kosztować...................................................e........................................ 154  6/.3;+ Silne prowadzenie ...................................................e...................................................e... 155 Wpływ nawiasów okrągłych ...................................................e...................................... 155 Optymalizacja wewnętrzna...................................................e................................................. 159 Rozpoznawanie pierwszego znaku ...................................................e............................ 159 Sprawdzanie obecności stałego fragmentu tekstu...................................................e...... 160 Proste powtarzanie ...................................................e...................................................e.. 160 Niepotrzebne małe kwantyfikatory ...................................................e............................ 162 Rozpoznanie długości ...................................................e................................................ 162 Rozpoznanie dopasowania ...................................................e......................................... 162 Rozpoznanie potrzeb...................................................e.................................................. 162 Zakotwiczenia łańcucha lub wiersza...................................................e.......................... 162 Buforowanie postaci skompilowanej ...................................................e......................... 163 Identyfikacja mechanizmu...................................................e.................................................. 165 NFA czy DFA?...................................................e...................................................e........ 165 NFA tradycyjny czy posiksowy? ...................................................e............................... 166 Rozwijanie pętli ...................................................e...................................................e............... 166 Metoda pierwsza: tworzenie wyrażenia na podstawie doświadczenia ......................... 167 Faktyczny wzór na „rozwinięcie pętli” ...................................................e...................... 168 Metoda druga: pogląd z góry ...................................................e..................................... 171 Metoda trzecia: nazwa hosta internetowego w cudzysłowach ..................................... 171 Obserwacje ...................................................e...................................................e.............. 172 Rozwijanie komentarzy w C...................................................e............................................... 173 Wyrażeniowy zawrót głowy ...................................................e...................................... 173 Sposób naiwny ...................................................e...................................................e........ 173 Rozwijanie pętli w języku C ...................................................e...................................... 176 Swobodne wyrażenie ...................................................e...................................................e.......177 Dopasowanie wspomagane ...................................................e........................................ 177 Czy można jeszcze szybciej? ...................................................e..................................... 178 Opakowanie...................................................e...................................................e............. 180 Nic nie zastąpi myślenia ...................................................e...................................................e.. 181 Różne oblicza optymalizacji ...................................................e...................................... 181  326/82-2+6).+-  Pytania, które powinny się pojawić...................................................e.................................... 185 Pozornie prosty grep… ...................................................e.............................................. 185 W tym rozdziale ...................................................e...................................................e...... 187 Język awk...................................................e...................................................e......................... 187 Różnice pomiędzy odmianami wyrażeń regularnych w awku ..................................... 188 Funkcje i operatory wyrażeń regularnych w awku ...................................................e.... 190 Tcl ...................................................e...................................................e.................................... 192 Argumenty wyrażeń regularnych...................................................e............................... 192 Korzystanie z wyrażeń regularnych Tcl-a...................................................e.................. 193 Optymalizacja wyrażeń w języku Tcl ...................................................e........................ 195 GNU Emacs ...................................................e...................................................e..................... 195 Łańcuchy Emacsa jako wyrażenia regularne ...................................................e............. 196 Emacsowa odmiana wyrażeń regularnych...................................................e................. 197 Wyniki dopasowania w Emacsie ...................................................e............................... 199 6/.3;+  Pomiar wydajności w Emacsie...................................................e................................... 200 Optymalizacja wyrażeń regularnych w Emacsie ...................................................e....... 201   6+ /2+6/19+62/ /6+   Metoda Perla ...................................................e...................................................e.................... 204 Wyrażenia regularne jako składnik języka ...................................................e................ 205 Największa siła Perla ...................................................e................................................. 206 Największa słabość Perla ...................................................e........................................... 207 Perl a problem jajka i kury ...................................................e......................................... 207 Przykład wprowadzający: analiza tekstu w formacie CSV .......................................... 208 Wyrażenia regularne a metoda Perla...................................................e.......................... 210 Perl bez tajemnic ...................................................e...................................................e..... 211 „Perlizmy” związane z wyrażeniami regularnymi ...................................................e............. 212 Kontekst wyrażenia regularnego...................................................e................................ 213 Zasięg dynamiczny a wynik dopasowania...................................................e................. 214 Zmienne specjalne po dopasowaniu...................................................e........................... 219 „Przetwarzanie cudzysłowowe” i interpolacja zmiennych ........................................... 221 Perlowa odmiana wyrażeń regularnych...................................................e.............................. 226 Kwantyfikatory zachłanne i leniwe...................................................e............................ 226 Grupowanie ...................................................e...................................................e............. 228 Punkty zakotwiczenia łańcucha ...................................................e................................. 233 Zakotwiczenie poprzedniego dopasowania ...................................................e............... 237 Punkty zakotwiczenia słów ...................................................e........................................ 241 Wygodne skróty i inne sposoby notacji ...................................................e..................... 242 Klasy znaków ...................................................e...................................................e.......... 244 Prawdziwe kłamstwa, czyli modyfikacja z użyciem symbolu e\Q i znaków pokrewnych ...................................................e................................................ 246 Operator dopasowania ...................................................e...................................................e.....247 Ograniczniki argumentu dopasowania...................................................e....................... 247 Modyfikatory dopasowania...................................................e........................................ 249 Określanie argumentu docelowego ...................................................e............................ 250 Inne efekty uboczne operatora dopasowania ...................................................e............. 251 Wartość zwracana przez operator dopasowania ...................................................e........ 252 Czynniki zewnętrzne wpływające na operator dopasowania........................................ 254 Operator podstawiania ...................................................e...................................................e..... 255 Argument podstawienia ...................................................e............................................. 255 Modyfikator /e...................................................e...................................................e......... 256 Kontekst i wartość zwracana...................................................e...................................... 258 Użycie modyfikatora /g w wyrażeniu, które może dopasować „nic”........................... 258 Operator split ...................................................e...................................................e................... 259 Podstawowe działanie operatora split ...................................................e........................ 259 Zaawansowane działanie operatora split...................................................e.................... 260 Zaawansowany argument dopasowania w split ...................................................e......... 261 Operator split w kontekście skalarnym...................................................e...................... 263 Argument dopasowania operatora split a nawiasy przechwytujące ............................. 263 Aspekty wydajności...................................................e...................................................e......... 264 „Jest na to wiele sposobów”...................................................e....................................... 265 Kompilacja wyrażenia, modyfikator /o i wydajność ...................................................e. 266  6/.3;+ Nietowarzyska zmienna $ i spółka...................................................e.......................... 271 Spadek wydajności wywołany modyfikatorem /i ...................................................e...... 277 Aspekty wydajności związane z podstawianiem ...................................................e....... 279 Testowanie ...................................................e...................................................e.............. 281 Usuwanie błędów wyrażenia regularnego ...................................................e................. 282 Funkcja study ...................................................e...................................................e.......... 284 Składamy wszystkie klocki...................................................e................................................. 286 Usuwanie końcowych i początkowych białych znaków............................................... 287 Dodawanie przecinków do liczb ...................................................e................................ 288 Usuwanie komentarzy z kodu w języku C...................................................e................. 288 Dopasowanie adresu poczty elektronicznej ...................................................e............... 289 Kilka słów na koniec...................................................e.................................................. 299 Uwagi na temat Perla4 ...................................................e............................................... 300 2036+-/.378)42/;7/-   Informacje ogólne...................................................e...................................................e............ 303 Rzemiosło wyrażeń regularnych ...................................................e................................ 303 O’Reilly Associates...................................................e................................................ 303 Wirtualna biblioteka oprogramowania OAK...................................................e............. 304 Archiwum GNU ...................................................e...................................................e...... 304 Yahoo!...................................................e...................................................e..................... 304 Inne adresy...................................................e...................................................e....................... 304 Awk ...................................................e...................................................e......................... 304 Pakiety biblioteczne dla języka C ...................................................e.............................. 304 Klasa wyrażeń regularnych Javy...................................................e................................ 304 Egrep ...................................................e...................................................e....................... 305 Emacs ...................................................e...................................................e...................... 305 Perl ...................................................e...................................................e.......................... 305 Python...................................................e...................................................e...................... 305 Tcl...................................................e...................................................e............................ 305  6316+.33,7o91+.6/71;/2+   #478+,/  9836/   #363;.   Przypomnijmy sobie problem powtórzonych słów, przedstawiony w poprzednim rozdziale. Wspo- mniano tam, że pełne rozwiązanie można byłoby napisać w zaledwie kilku linijkach Perla. Przy- kład znajduje się poniżej: $/ = .\n ; while ( ) { next if !s/\b([a-z]+)((\s| [^ ]+ )+)(\1\b)/\e[7m$1\we[m$2\e[7m$4\e[m/ig; s/^([^\e]*\n)+//mg; # usuwamy nieoznaczone wiersze s/^/$ARGV: /mg; # rozpoczynamy wiersze od nazwy pliku print; } Tak, to już cały program. Zapewne nie jest on jeszcze całkowicie zrozumiały, chodzi tu tylko o ukazanie możliwości, których nie posiada egrep i zwiększenie apetytu Czytelnika na prawdziwą siłę wyjrażeń regularnych — nie- mal całe działanie powyższego programu opiera się na tjrzech takich wyrażeniach: \b([a-z]+)((\s| [^ ]+ +)+)(\1\b) ^([^\e]*\n)+ ^ Na pewno zrozumiałe jest ostatnie z nich, ^(cid:2). W pozostałych jednak występują elementy nie oma- wiane w poprzednim rozdziale (choć o symbolu \b(cid:2) napisaliśmy krótko na stronie 39, wspomina- jąc, że czasem reprezentuje on granicę słowa — tę samą rolę pełni on także tutaj). Wynika to z faktu, że odmiana wyrażeń regularnych zastosowana w Perlu różni się od tej z egrepa. Różne są niektóre sposoby zapisu, a poza tym Perl udostępnia o wiele bogatszy zestaw metaznaków. Przekonamy się o tym na przykładach zamieszczonych w tym rozdziale. Perl umożliwia o wiele bardziej zaawansowane użycie wyrażeń regularnych niż egrep. Dzięki przykładom w Perlu poznamy dalsze sposoby wykorzystania wyrażeń regularnych i — co ważnie- jsze — zobaczymy, jak zachowują się w innym kontekścije niż w przypadku programu egrep. C:\Andrzej\PDF\Wyrażenia regularne\02-11.doc — strona 45  3.+o  6o+.;6+ /q6/19+62- Przedstawiana tu odmiana wyrażeń regularnych jest podobna do opisanej w poprzednim rozdziale, choć trochę się od niej różni. Omawiane w tym rozdziale przykładowe problemy, takie jak weryfikacja danych wprowadzanych przez użytkownika czy operacje na nagłówkach poczty elektronicznej, staną się okazją do dalszego zagłębiania się w krainę wyrażeń regularnych. Przyjrzymy się pokrótce Perlowi i przeanalizujemy niektóre procesy myślowe związane z budowaniem wyrażeń regularnych. Z tak wyznaczonej ścieżki będziemy jednak co pewien czas zbaczać i omawiać inne ważne pojęcia. Jako język programowania, Perl nie jest jakimś wyjątkowym zjawiskiem. Równie dobrze można by było wykorzystać dowolny inny zaawansowany język (np. Tcl, Python, czy nawet elisp programu GNU Emacs) jednak Perl jest tu najodpowiedniejszy dlatego, że spośród wymienionych języków w nim właśnie wyrażenia regu- larne są najgłębiej zakorzenione; jest też chyba najszerzej dostępny. Perl posiada również wiele użytecznych, zwięzłych konstrukcji do operowania na danych, dzięki którym sam wykonuje znaczną część „ciężkiej roboty” i pozwala skoncentrować się na właściwych wyrażeniach regularnych. Aby powyższe słowa brzmiały bardziej wiarygodnie, przypomnimy przykład z analizowaniem plików ze strony 18. Wykorzystano tu właśnie Perla, a całe polecenie brzmiało następująco: perl -0ne print $ARGV\n if s/ResetSize//ig != s/SetSize//iwg * Być może nie jest ono jeszcze dla Czytelnika zrozumiałe, ale samą zwartością rozwiązania na pewno robi wrażenie. Trzeba tu jednak pamiętać o uniknięciu pułapek języka, miejmy bowiem na uwadze fakt, że roz- dział ten koncentruje się na wyrażeniach regularnych. Przypomina to nieco słowa, które pewien profesor informatyki skierował do studentów pierwszego roku: „Teraz będziemy poznawać zaga- dnienia informatyczne, a do ich zademonstrowania posłużymy się Pascalem” (Pascal to tradycyjny język programowania, pierwotnie przeznaczony do nauczjania).1 Ponieważ nie wymaga się tu od Czytelnika znajomości Perla, przed omówieniem przykładów za- mieszczono wprowadzenie (pewnej podstawowej wiedzy o Perlu wymaga za to rozdział 7, prze- dstawiający istotne szczegóły tego języka). Nawet osobom, które mają doświadczenie z różnymi językami programowania, Perl może na pierwszy rzut oka wydać się odmienny — ma bardzo uproszczoną i czasem dziwną składnię. Prezentowane przykłady nie są może „złe” pod względem stylu programowania w tym języku, ale nie są też „doskonałe”. Dążąc do zrozumiałości przykładów może nie wykorzystaliśmy wszystkiego, co Perl może zaoferować — programy są tu przedstawione raczej w sposób ogólny, niemal jako „pseudokod”. Można natomiast tu znaleźć naprawdę ciekawe zastosowanie wyrażeń regularnych. /66(cid:8)8/;463;+./2/ Perl to język programowania o ogromnych możliwościach. Został stworzony przez Larry’ego Walla w późnych latach osiemdziesiątych, a przy jego budowie czerpano pomysły z innych języ- ków. Wiele sposobów przetwarzania tekstu i wyrażeń rjegularnych pochodzi z awka i seda, te nato- miast znacznie się różnią od „tradycyjnych” języków, takich jak C czy Pascal. Perl jest dostępny dla wielu systemów, w tym dla DOS-u, Windows, MacOS, OS/2, VMS i Uniksa. Jego możliwości objawiają się szczególnie przy przetwarzaniu tekstu; jest też bardzo często wykorzystywany do tworzenia skryptów CGI na potrzeby serwisów WWW (programy CGI służą do tworzenia i wy- świetlania dynamicznych stron WWW). Informacje o tym, jak zdobyć kopię Perla dla swojego 1 Podziękowania za przykład należą się Williamowi F. aMatonowi oraz jego profesorowi. C:\Andrzej\PDF\Wyrażenia regularne\02-11.doc — strona 46 46o+.+-  systemu zamieszczono w dodatku A. Omówienie w tej książce dotyczyć będzie Perla w wersji 5.003, ale prezentowane tu przykłady zostały napisane tak, że będą działały w wersji 4.036 lub późniejszych.2 Spójrzmy na prosty przykład: $celsjusz = 30; $fahrenheit = ($celsjusz * 9 / 5) + 32; # obliczamy stopnie Fahrenheita print $celsjusz C to $fahrenheit F.\n ; # drukujemy obie temperatury Po wykonaniu programu otrzymamy taki wynik: 30 C to 86 F. Proste zmienne, takie jak $fahrenheit czy $celsjusz, zawsze rozpoczynają się znakiem dola- ra i mogą zawierać liczbę lub dowolną ilość tekstu (w tym przykładzie przypisano im tylko liczby). Komentarze rozpoczynają się znakiem # i kończą wraz z końcem wiersza. Dla osób przyzwyczajo- nych do tradycyjnych języków programowania, takich jak C czy Pascal, prawdopodobnie najbardziej zaskakujące jest, iż zmienne mogą znajdować się wewnątrz łańcuchów objętych cudzysłowami. W łańcuchu $celsjusz C to $fahrenheit F.\n pod obie zmienne podstawiane są ich wartości. Tak uzyskany wiersz jest następnie wyświetlajny (\n reprezentuje znak nowego wiersza). W Perlu można też używać instrukcji sterujących, podobjnie jak w innych popularnych językach: $celsjusz = 20; while ($celsjusz = 45) { $fahrenheit = ($celsjusz * 9 / 5) + 32; # obliczamy Fahrenheita print $celsjusz C to $fahrenheit F.\n ; $celsjusz = $celsjusz + 5; } Treść zawarta wewnątrz pętli while jest wykonywana dopóty, dopóki warunek (w tym przypadku brzmiący: $celsjusz = 45) jest prawdą. Jeśli powyższy tekst umieścimy w pliku, np. o na- zwie temperatury, będziemy mogli uruchomić taki program wprost z wiersjza poleceń: perl -w temperatury 20 C to 68 F. 25 C to 77 F. 30 C to 86 F. 35 C to 95 F. 40 C to 104 F. 45 C to 113 F. Opcja -w nie jest konieczna, nie ma też bezpośrednio nic wspólnego z wyrażeniami regularnymi. Informuje po prostu Perla, aby dokładniej sprawdzał wykonywany program i ostrzegał użytkownika za każdym razem, gdy znajdzie jakąś nieprawidłowość (np. niezainicjalizowane zmienne — zmie- nne nie muszą być w Perlu wcześniej deklarowane). Opcję tę zastosowano tu tylko po to, aby wpoić Czytelnikom nawyk jej używania. 2 Choć wszystkie przykłady w tym rozdziale dają się uruchomić we wcześniejszych wersjach Perla, autor bardzo namawia do korzystania z wersji 5.002 lub późniejszej, bardzo natomiast odradza korzystanie z archaicznej wersji 4.036, chyba że naprawdę nie ma innego wyjścia. C:\Andrzej\PDF\Wyrażenia regularne\02-11.doc — strojna 47  3.+o  6o+.;6+ /q6/19+62- Wyrażenia regularne są w Perlu wykorzystywane na rozmaite sposoby. Najprostszy z nich polega na sprawdzeniu, czy wyrażenie regularne może zostać dopasowane do tekstu przechowywanego w zmiennej. Poniższy fragment programu sprawdza, czy w zmiennej $odpowiedz znajdują się wyłącznie cyfry: if ($odpowiedz =~ m/^[0-9]+$/) { print tylko cyfry\n ; } else { print nie tylko cyfry\n ; } Składnia pierwszego wiersza może wydawać się nieco osobliwa. Wyrażenie regularne to ^[0- 9]+$(cid:2), natomiast otaczająca je konstrukcja m/…/ wskazuje Perlowi, co trzeba z tym wyrażeniem zrobić. Litera m oznacza, że Perl ma podjąć próbę dopasowania wyrażenia regularnego do zmie- nnej, natomiast ukośniki wyznaczają granice samego wyrażenia. Symbol =~ łączy konstrukcję m/…/ z dopasowywanym łańcuchem znaków — w tym przypadku łańcuch ten jest zawarty w zmien- nej $odpowiedz. Nie należy mylić sekwencji =~ z = lub ==, ponieważ jest to coś zupełnie innego. Operator == te- stuje, czy dwie liczby są takie same (do testowania identyczności łańcuchów służy, jak się wkrótce przekonamy, operator eq). Operator = wykorzystywany jest do przypisywania wartości zmiennej, np. $celsjusz = 20. Wreszcie zapis =~ służy do łączenia konstrukcji wyszukującej z prze- szukiwanym łańcuchem znaków (w przykładzie konstrukcją wyszukującą jest m/^[0-9]+$/, a przeszukiwanym łańcuchem — $odpowiedz). Być może wygodniej byłoby czytać zapis =~ jako „pasuje do” — wtedy zapis: if ($odpowiedz =~ m/^[0-9]+$/) { można by przeczytać jako: „jeśli tekst w zmiennej $odpowiedz pasuje do wyrażenia regularnego ^[0-9]+$(cid:2), wtedy…” Wynik całego wyrażenia $odpowiedz =~ m/^[0-9]+$/ ma wartość prawda, jeśli wyrażenie ^[0-9]+$(cid:2) pasuje do łańcucha $odpowiedz; w przeciwnym razie ma wartość fałsz. Instru- kcja if korzysta potem z tej wartości, decydując na jej podjstawie, który komunikat wydrukować. Zauważmy, że test o postaci $odpowiedz =~ m/[0-9]+/ (taki sam jak poprzednio, ale bez daszka na początku i dolara na końcu) zwróciłby wartojść prawda, jeśli zmienna $odpowiedz za- wierałaby przynajmniej jedną cyfrę w dowolnym miejscu. Symbole ^…$(cid:2) zapewniają, że zmienna $odpowiedz musi zawierać wyłącznie cyfry. Połączmy dwa ostatnie przykłady. Poprosimy użytkownika o wpisanie jakiejś wartości, przypiszemy tę wartość zmiennej, a potem za pomocą wyrażenia regularnego sprawdzimy, czy jest liczbą. Jeśli tak — program wyświetli odpowiednik w stopniach Fahrenheita. Jeśli nie, pojawi się ostrzeżenie. print Wpisz temperaturę w stopniach Celsjusza:\n ; $celsjusz = STDIN ; # wczytujemy jeden wiersz podany przez użytkownika chop($celsjusz); # usuwamy znak koñca wiersza ze zmiennej $celsjusz if ($celsjusz =~ m/^[0-9]+$/) { $fahrenheit = ($celsjusz * 9 / 5) + 32; # obliczamy stopnie Fahrenheita C:\Andrzej\PDF\Wyrażenia regularne\02-11.doc — strona 48 79;+2/8/789+433-;6+ /q6/19+62-  print $celsjusz C = $fahrenheit F\n ; } else { print Oczekiwano wprowadzenia liczby, zapis \ $celsjusz\ w jest niezrozumiały.\n ; } Można zauważyć, że sposób „anulowania” znaków cudzysłowu w ostatniej instrukcji print jest podobny do sposobu, w jaki eliminuje się specjalne znaczenie metaznaków w wyrażeniu regular- nym. Więcej szczegółów na ten temat zamieszczono kilka stron dalej ((cid:1)54), w części Mała dygresja — Firmament metaznaków. Spróbujemy zapisać nasz program w pliku c2f i uruchomić go: perl -w c2f Wpisz temperaturę w stopniach Celsjusza: 22 22 C = 71.599999999999994316 F Niestety, wygląda na to, że zwykła funkcja print nie radzi sobie najlepiej z liczbami zmienno- przecinkowymi. Aby nie zagłębiać się tutaj we wszystkie detale Perla, zasugerujemy użycie w tym miejscu funkcji printf (ang. print formatted) — wydruk będzie wyglądać wtedy lepiej (printf przypomina funkcję printf z języka C oraz funkcje formatujące tekst z języków Pascal, Tcl, elisp i Python): printf .2f C = .2f F\n , $celsjusz, $fahrenheit; Nie spowoduje to zmiany wartości zmiennych, a jedynie sposobu ich wyświetlania. Działanie pro- gramu powinno teraz przebiegać następująco: perl -w c2f Wpisz temperaturê w stopniach Celsjusza: 22 22.00 C = 71.60 F co oczywiście wygląda o wiele lepiej. 6o+., 76/-;783- Nasz przykład dobrze byłoby rozszerzyć tak, by można było podawać wartości ujemne i ułamkowe. Część matematyczna programu nie wymaga zmian — liczby całkowite i zmiennoprzecinkowe Perl traktuje tak samo. Trzeba jednak zmienić wyrażenie regularne tak, by nie powodowało wy- świetlenia komunikatu o błędzie w przypadku podania liczby ułamkowej lub ujemnej. W tym celu należy na początku dopisać wyrażenie -?(cid:2), co pozwoli rozpocząć treść zmiennej znakiem minusa. Właściwie można nawet dodać ciąg [-+]?(cid:2), tak by na początku dopuszczalny był również plus. Aby dopuścić możliwość wpisania części dziesiętnej, dopiszemy wyrażenie (\.[0-9]*)?(cid:2). Sekwencja unikowa z kropką pasuje do dosłownego znaku kropki (w krajach anglojęzycznych, a także w Perlu, część ułamkową oddziela się od całkowitej kropką, a nie, jak w Polsce, przecin- kiem), a więc wyrażenie \.[0-9]*(cid:2) odpowiada kropce, po której znajduje się dowolna liczba dowolnych cyfr. Ponieważ wyrażenie \.[0-9]*(cid:2) jest ujęte w znaki (…)?(cid:2), będzie ono opcjo- nalne jako całość (jest to logicznie różne od \.?[0-9]*(cid:2) — tutaj cyfry zostałyby dopasowane nawet wtedy, gdyby nie dopasowano kropki). Cały wiersz kontrolujący poprawność wpisu wygląda więc jnastępująco: if ($celsjusz =~ m/^[-+]?[0-9]+(\.[0-9]*)?$/) { C:\Andrzej\PDF\Wyrażenia regularne\02-11.doc — strojna 49  3.+o  6o+.;6+ /q6/19+62- Teraz już można wpisywać takie liczby jak 32, -3.723 czy +98.6. Wyrażenie to nie jest jednak idealne: nie pozwala na wpisywanie liczb rozpoczynających się od kropki (np. .357). Oczywiście użytkownik może zawsze podać na początku zero (czyli 0.357), nie jest to więc jakaś ogromna wada. Problem ułamków ma jeszcze inne ciekawe aspekty, o których szczegółowo powiemy w rozdziale 4. ((cid:1)135). #989,3-2/9.+2/13.34+73;+2+ Rozbudujmy nasz przykład jeszcze bardziej i pozwólmy na wpisywanie wartości albo w stopniach Celsjusza, albo Fahrenheita. Użytkownik będzie do wpisywanej liczby dodawał odpowiednio C lub F. Aby nasze wyrażenie regularne na to pozwoliło, wystarczy dodać — po części dopasowują- cej liczbę — zapis [CF](cid:2). Ale przecież musimy także zmienić resztę programu tak, by rozpozna- wał, w jakiej skali wpisano temperaturę i na jaką najleży ją przeliczyć. Perl, podobnie jak inne języki wykorzystujące wyrażenia regularne, posiada zestaw użytecznych zmiennych pozwalających na odwoływanie się do tekstu dopasowanego wcześniej do wyrażeń regularnych ujętych w nawiasy. W pierwszym rozdziale powiedzieliśmy, że niektóre wersje pro- gramu egrep rozpoznają metasekwencje \1(cid:2), \2(cid:2), \3(cid:2) itd. umieszczone wewnątrz samego wy- rażenia regularnego. Perl także obsługuje te metasekwencje, a oprócz tego pozwala odwoływać się do fragmentów wyrażenia regularnego na zewnątrz niego, już po zakończeniu dopasowywania. Takie odwołania realizowane są za pomocą zmiennych $1, $2, $3 itd. Wygląda to może trochę dziwnie, ale to są zmienne, tyle że ich nazwy są liczbami. Perl nadaje im wartości za każdym ra- zem, gdy dopasowanie wyrażenia regularnego się powiedzie. Metaznaku \1(cid:2) można użyć we- wnątrz wyrażenia regularnego w celu odwołania do tekstu dopasowanego wcześniej podczas tej samej próby dopasowywania. Natomiast zmiennej $1 należy użyć, by odwołać się do dopaso- wanego tekstu w programie już po zakończeniu udanego dopasowania. Aby zachować przejrzystość przykładu i ułatwić przyswojenie nowych wiadomości, usuniemy na chwilę z naszego wyrażenia część związaną z ułamkami dziesiętnymi (powrócimy do nich wkró- tce). Żeby poznać działanie zmiennej $1, porównajmy poniższe dwa wyrażenia: $celsjusz =~ m/^[-+]?[0-9]+[CF]$/ $celsjusz =~ m/^([-+]?[0-9]+) ([CF])$/ Czy dodanie nawiasów okrągłych zmienia znaczenie wyrażenia? Aby uzyskać odpowiedź na to pytanie, musimy sprawdzić, czy nawiasy te:   grupują elementy na potrzeby gwiazdki lub innego kwantyjfikatora; ograniczają wyrażenia rozdzielone znakiem |(cid:2). Odpowiedź na powyższe pytania brzmi „nie”, a więc obydwa wyrażenia pasują do tego samego ciągu. Jednak nawiasy okrągłe obejmują dwa podwyrażenia — te „interesujące” z naszego punktu widzenia. Jak pokazano na rysunku 2.1, zmienna $1 będzie zawierała wpisaną liczbę, zaś zmienna $2 — albo literę C, albo F. Jeśli teraz spojrzymy na sieć działań przedstawioną na rysunku 2.2, zobaczymy, że znając zawartość tych zmiennych możemy w prosty sposób pokierować działaniem programu po dopasowaniu. Zakładając, że pokazany dalej program nazwiemy konwersja, jego użycie wyglądałoby następująco: perl -w konwersja Wpisz temperaturę (np. 32F, 100C): 39F C:\Andrzej\PDF\Wyrażenia regularne\02-11.doc — strona 50 79;+2/8/789+433-;6+ /q6/19+62-  792/ +;+7™46/-;89-/˜ 792/  1368.+o+2+46316+932;/689 -/138/4/6+896 3.89 C = 39.00 F perl -w konwersja Wpisz temperaturę (np. 32F, 100C): 39C 39.00 C = 102.20 F perl -w konwersja Wpisz temperaturę (np. 32F, 100C): ojejku Oczekiwano wprowadzenia temperatury, zapis ojejku jest niezrozumiały. print Wpisz temperaturę (np. 32F, 100C):\n ; $lancuch = STDIN ; # wczytujemy jeden wiersz podany przez użytkownika C:\Andrzej\PDF\Wyrażenia regularne\02-11.doc — strojna 51  3.+o  6o+.;6+ /q6/19+62- chop($lancuch); # usuwamy znak końca wiersza ze zmiennej $celsjusz if ($lancuch =~ m/^([-+]?[0-9]+)([CF])$/) { # jeżeli znajdziemy się w tym miejscu programu, # to znaczy, że dopasowanie się powiodło # $1 zawiera liczbę, a $2 literę C lub F $liczba = $1; # zachowujemy wartości w nazwanych zmiennych, $typ = $2; # co uprości czytanie pozostałej części programu if ($typ eq C ) { # eq sprawdza, czy 2 łańcuchy są identyczne # podano temperaturę w Celsjuszach, przeliczamy na F. $celsjusz = $liczba; $fahrenheit = ($celsjusz * 9 / 5) + 32; } else { # a więc jednak podano Fahrenheita -- przeliczamy na Ce. $fahrenheit = $liczba; $celsjusz = ($fahrenheit - 32) * 5 / 9; } # w tej chwili znamy już obie temperatury, więc # wyświetlamy wynik printf .2f C = .2f F\n , $celsjusz, $fahrenheit; } else { print Oczekiwano wprowadzenia temperatury, zapis \ $lancuch\w jest niezrozumiały.\n ; } 34+73;+2++2/13;+2/ Nasz program ma następującą strukturę logiczną: if ( test logiczny ) { … DŁUGIE PRZETWARZANIE jeżli zwrócono wynik prawda … } else { … tylko trochę przetwarzania, jeżli zwrócono wynik faelsz … } Każdy student programowania strukturalnego wie (lub powinien wiedzieć), że kiedy jedna gałąź konstrukcji if jest krótka, a druga długa, to — o ile to tylko jest praktycznie wykonalne — lepiej umieścić tę krótką na początku. Dzięki temu else jest bliżej if, co ułatwia przetwarzanie kodu. Aby zrobić tak z naszym programem, musimy odwrócić sens testu. Krótsza część to ta, która mó- wi „jeśli nie pasuje”, a więc test powinien zwracać wartość prawda wtedy, gdy dopasowanie się nie powiedzie. Można to, zrobić zamieniając zapis =~ na !~, tak jak to pokazano poniżej: $lancuch !~ m/^([-+]?[0-9]+([CF])$/ Wyrażenie regularne i badany łańcuch pozostają bez zmian. Jedyna różnica polega na tym, że wynik całej kombinacji przyjmuje teraz wartość fałsz, jeśli wyrażenie regularne pasuje do łańcucha oraz wartość prawda w przeciwnym przypadku. Jeśli nastąpi dopasowanie, zmiennym $1, $2 itd. zostaną tak samo nadane wartości. Dlatego ta część naszego progrjamu wyglądałaby teraz następująco: if ($lancuch !~ m/^([-+]?[0-9]+)([CF])$/) { print Oczekiwano wprowadzenia temperatury, zapis \ $lancuch\ jestw niezrozumiały.\n ; } else { # jeżeli znajdziemy się w tym miejscu programu, # to znaczy, że dopasowanie się powiodło # $1 zawiera liczbę, a $2 literę m C lub F … } C:\Andrzej\PDF\Wyrażenia regularne\02-11.doc — strona 52 79;+2/8/789+433-;6+ /q6/19+62-  6/4+8+2/;6+ /q6/19+62- W zaawansowanych językach programowania, takich jak Perl, wyrażenia regularne mogą w du- żym stopniu przeplatać się z resztą programu. Aby przedstawić to na przykładzie, wprowadzimy teraz do naszego programu trzy pożyteczne zmiany: umożliwimy wpisywanie liczb ułamkowych, tak jak to robiliśmy wcześniej, zezwolimy na wpisywanie małych liter f i c oraz zezwolimy na występowanie spacji pomiędzy liczbą a literą. Po takich zmianach użytkownik będzie mógł wpisać np. 98.6f. Jak wspomniano wcześniej, obsługę ułamków realizuje się poprzez dodanie wyrażenia (\.[0- 9]*)?(cid:2): if ($lancuch =~ m/^([-+]?[0-9]+(\.[0-9]*)?)([CF])$/) Zauważmy, że nowy fragment dodano wewnątrz pierwszej pary nawiasów okrągłych. Ponieważ za pomocą tej pary nawiasów identyfikujemy liczbę do przeliczenia, musimy przechwycić ją wraz z ułamkami. Chociaż dodatkowa para nawiasów okrągłych służy wyłącznie do grupowania elemen- tów na potrzeby znaku zapytania, powoduje ona efekt uboczny polegający na przypisaniu do zmien- nej znajdującej się wewnątrz nich wartości. Ponieważ nawias otwierający jest w tym przypadku drugim nawiasem otwierającym od lewej strony, wartość przypisana zostaje do zmiennej $2. Do- brze obrazuje to rysunek 2.3. 792/  +;+7+12/ . 32/ Widzimy, w jaki sposób nawiasy otwierające i zamykające są zagnieżdżone jedne w drugich. Do- danie pary nawiasów przed wyrażeniem [CF](cid:2) nie powoduje bezpośrednio zmiany jego znacze- nia. Jest jednak wpływ pośredni: teraz nawiasy otaczające to wyrażenie stanowią już trzecią parę nawiasów, a to znaczy, że zmiennej $typ musimy przypisać wartość zmiennej $3, a nie $2. Umożliwienie wpisywania spacji pomiędzy liczbą a literą nie jest aż takie skomplikowane. Wie- my, że „czysta” spacja w wyrażeniu regularnym odpowiada dokładnie jednej spacji w dopasowy- wanym tekście, a więc ciąg *(cid:2) pasuje do dowolnej liczby spacji (może też nie być jich wcale): if ($lancuch =~ m/^([-+]?[0-9]+(\.[0-9]*)?) *([CF])$/) Już w ten sposób zapewnia się pewną elastyczność dopasowania. Ponieważ jednak chcemy stwo- rzyć coś, co ma być rzeczywiście użyteczne w praktyce, spróbujmy stworzyć wyrażenie regularne pozwalające na wprowadzanie także innych białych znaków, na przykład często spotykanych zna- C:\Andrzej\PDF\Wyrażenia regularne\02-11.doc — strojna 53  3.+o  6o+.;6+ /q6/19+62- ków tabulacji. Oczywiście wyrażenie (cid:4)*(cid:2) uniemożliwi użycie zwykłych spacji, musimy więc stworzyć klasę znaków zawierającą i znaki tabulacji, i spacje: [(cid:4)]*(cid:2). A teraz krótka kartkówka: czym różni się to wyrażenie od (*|(cid:4)*)(cid:2)? L Odpowiedź znajduje się na stronie 56. W tej książce spacje i znaki tabulacji łatwo odróżnić, zostały bowiem zaznaczone specjalnymi symbolami  oraz (cid:4). Niestety, na ekranie nie jest już tak łatwo. Jeśli widzimy zapis w rodzaju [ ]*, możemy zgadywać, że pewnie jest to spacja i znak tabulacji, ale nie upewnimy się, dopóki tego nie sprawdzimy. Perl ułatwia nam nieco życie, udostępniając metaznak \t(cid:2). Pasuje on po prostu do znaku tabulacji, a jego jedyną zaletą w stosunku do „prawdziwego” znaku jest to, że le- piej go widać (i dlatego będziemy z niego korzystali w wyrażeniach). Zatem zamieniamy zapis [ (cid:4)]*(cid:2) na [\t]*(cid:2) A oto kilka innych wygodnych metaznaków: \n(cid:2) (newline — znak nowego wiersza), \f(cid:2) (form feed — znak wysuwu strony) oraz \b(cid:2) (backspace — znak cofania). Ale chwileczkę — wcześniej przypisaliśmy \b(cid:2) do granicy słowa. Cóż więc oznacza ten znak? Otóż oznjacza on i to, i to! +o+.16/7+06+/28/8+2+(cid:24); We wcześniejszych przykładach występowała sekwencja \n, jednak nie znajdowała się ona w wyraże- niu regularnym, tylko w łańcuchu znaków. Łańcuchy Perla wykorzystują własne metaznaki, w ogóle niezwiązane z metaznakami wyrażeń regularnych. Nowi programiści często mylą te dwa obszary. Jak się jednak okazuje, niektóre metaznaki łańcuchów mają — dla ułatwienia — podobne znacze- nia, jak te same metaznaki wyrażeń regularnych. Na przykład metaznak \t służy do wstawiania znaku tabulacji do łańcucha, a podobny metaznak \t(cid:2) — odpowiada znakowi tabulacji wewnątrz wyrażenia regularnego. Takie podobieństwa są wygodne, trzeba jednak pamiętać, by ich nie mylić. Może wydaje się to mało ważne dla prostego przykładu znaku \t, ale, jak zobaczymy przy okazji omawiania in- nych języków i narzędzi, wiedza o tym, które metaznaki są wykorzystywane w jakiej sytuacji, jest niezwykle istotna. Konflikty pomiędzy metaznakami nie powinny być już niczym nowym. W rozdziale 1., przy okazji omawiania programu egrep, wyrażenie regularne ujmowaliśmy w apostrofy. Cały wiersz poleceń wpisywany jest po znaku zachęty, a interpreter rozpoznaje własne metaznaki. W pojęciu interpretera metaznakiem jest np. spacja — oddziela ona polecenie od argumentów oraz poszczególne argumenty między sobą. W wielu interpreterach apostrofy informują, że wewnątrz nich inne metaznaki mają pozostać niezinterpretowane (w przypadku DOS-u takie znaczenie mają cudzysłowy). Użycie apostrofów w przypadku interpretera pozwala na zastosowanie w wyrażeniu regularnym znaków spacji. Bez apostrofów znaki te zostałyby przechwycone przez interpreter poleceń, a nie przekazane do programu egrep. Wiele interpreterów rozpoznaje także inne metaznaki — $, *, ? itd. — a przecież te z dużym prawdopodobieństwem mogąj pojawić się w wyrażeniu regularnym. Cała ta opowieść o metaznakach interpretera i metaznakach w łańcuchach Perla nie ma nic wspólne- go z samymi wyrażeniami regularnymi, jest natomiast silnie związana ze sposobem korzystania z wyrażeń regularnych w praktyce. W wielu miejscach książki natkniemy się na złożone nie- raz problemy, w których będzie trzeba wykorzystać możliwość „nakładania się” różnych pozio- mów interpretacji metaznaków. C:\Andrzej\PDF\Wyrażenia regularne\02-11.doc — strona 54 79;+2/8/789+433-;6+ /q6/19+62-  Wróćmy jednak do podwójnego znaczenia metaznaku \b(cid:2). Tym razem sprawa jak najbardziej dotyczy wyrażeń regularnych. W Perlu sekwencja taka oznacza normalnie granicę słowa (ang. boundary), ale wewnątrz klasy znaków służy do dopasowania znaku cofania (backspace). Wsta- wianie granicy słowa wewnątrz klasy znaków nie miałoby sensu, a więc w takich miejscach Perl może go interpretować inaczej. Zamieszczone w pierwszym rozdziale ostrzeżenie, że „pod- język” klasy znaków jest inny od właściwego języka wyrażeń regularnych, jest na pewno aktualne w przypadku Perla (i wszystkich innych odmian wyrażejń regularnych). +o/2+9683;37 Przy omawianiu białych znaków poprzestaliśmy na wyrażeniu [\t]*(cid:2). Takie rozwiązanie dzia- ła, ale mechanizm wyrażeń regularnych Perla pozwala zapisać je znacznie prościej. Podobnie jak metaznak \t(cid:2) reprezentuje znak tabulacji, \s(cid:2) to skrótowy zapis oznaczający całą klasę znaków zawierającą dowolny „biały znak”, czyli między innymi spację, znak tabulacji, nowego wiersza i powrotu karetki (ang. carriage return). W naszym przykładzie znaki nowego wiersza i powrotu karetki nie są i tak do niczego potrzebne, ale zapis \s*(cid:2) jest prostszy niż [\t]*(cid:2). Wkrótce przyzwyczaimy się do widoku tego symbolu; jego znaczenie łatwo można zrozumieć nawet w zło- żonych wyrażeniach regularnych. Nasz test przybierze teraz postać: $lancuch =~ m/^([-+]?[0-9]+(\.[0-9]*)?)\s*([CF])$/ Ostatnim udogodnieniem miało być umożliwienie wprowadzania zarówno wielkich, jak i małych liter. Oczywiście, najprostszym sposobem byłoby dodanie małych liter do klasy znaków: [CFcf](cid:2), jednak przedstawimy tu jeszcze inne rozwiązanie: $lancuch =~ m/^([-+]?[0-9]+(\.[0-9]*)?)\s*([CF])$/i Znak i jest tutaj modyfikatorem, a umieszczenie go po konstrukcji m/…/ jest dla Perla wskazówką, że przy dopasowywaniu nie należy brać pod uwagę wielkości liter. Litera i nie jest częścią wy- rażenia regularnego, lecz konstrukcji składniowej m/…/, która mówi Perlowi, co należy zrobić z podanym wyrażeniem regularnym. Ponieważ nieco kłopotliwe byłoby ciągłe nazywanie wspo- mnianego znaku „modyfikatorem i”, zazwyczaj wykorzystuje się zapis /i (choć w praktyce dodatkowy ukośnik przed literą jest zwykle pomijany). W tym rozdziale poznamy jeszcze modyfi- kator /g; na inne przyjdzie czas w dalszych częściach książkij. Wypróbujmy teraz nasz program: perl –w konwersja Wpisz temperaturę (np. 32F, 100C): 32 f 10.0 C = 32.00 F perl –w konwersja Wpisz temperaturę (np. 32F, 100C): 50 c 10.00 C = 50.00 F Coś się nie zgadza. Kiedy za drugim razem wpisano 50 Celsjusza, zostały one zinterpretowane ja- ko 50 Fahrenheita. Dlaczego? Spójrzmy jeszcze raz na odpowijednią część programu: if ($lancuch =~ m/^([-+]?[0-9]+(\.[0-9]*)?)\s*([CF])$/i) { … $typ = $3; # zachowujemy wartości w nazwanych zmiennych, C:\Andrzej\PDF\Wyrażenia regularne\02-11.doc — strojna 55  3.+o  6o+.;6+ /q6/19+62- ++/786(cid:8) 2-+43!.;6+ /2/ (cid:2)(cid:2)(cid:2)(cid:2)(cid:3)(cid:2)(cid:2)(cid:2)(cid:2)+ (cid:6)(cid:3)(cid:2)(cid:2)(cid:2)(cid:2)(cid:3)(cid:8)(cid:2)(cid:2)(cid:2)(cid:2) L Odpowiedź na pytanie ze strony 54 Wyrażenie (*|(cid:4)*)(cid:2) odpowiada albo *(cid:2) albo (cid:4)*(cid:2), czyli pasuje do kilku spacji (lub żadnej), albo kilku znaków tabulacji (lub żadnego). Nie umożliwia ono jednak dopasowa- nia mieszaniny spacji i znaków tabulacji. [(cid:4)]*(cid:2) pasuje do wyrażenia [(cid:4)](cid:2) powtórzonego dowolną liczbę razy. W łańcuchu „(cid:4)” takie wyrażenie dopasowywane jest trzy razy, najpierw do znaku tabulacji, a po- tem dwóch spacji. [(cid:4)]*(cid:2) to logicznie to samo co (|(cid:4))*(cid:2), jednak użycie klasy znaków jest często o
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

Wyrażenia regularne
Autor:

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: