Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00255 005706 13612199 na godz. na dobę w sumie
Wyrażenia regularne. Receptury - książka
Wyrażenia regularne. Receptury - książka
Autor: , Liczba stron: 520
Wydawca: Helion Język publikacji: polski
ISBN: 978-83-246-2510-9 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> programowanie >> techniki programowania
Porównaj ceny (książka, ebook, audiobook).

Poznaj i wykorzystaj możliwości regexpów w codziennej pracy!

Wyrażenie regularne (ang. regexp) to inaczej wzorzec, który określa zbiór dopasowanych łańcuchów znaków. Brzmi to prosto. Jednak przy pierwszym spotkaniu z wyrażeniami wcale tak nie jest. Zbiór znaków i symboli składający się na wyrażenie regularne w niczym nie przypomina rzeczy, którą chciałbyś się zająć. Wyrażenia regularne zawsze kojarzą się początkującemu użytkownikowi co najmniej z wiedzą tajemną, a często wręcz z magią. Warto im się jednak przyjrzeć, poznać je i polubić, a następnie wykorzystać możliwości, jakie w nich drzemią.

Jedno jest pewne - te możliwości są spore. Autorzy błyskawicznie zaprzyjaźnią Cię z wyrażeniami regularnymi - książka należy bowiem do znanej serii Receptury, cechującej się tym, że proces nauki jest oparty na analizie rozwiązań prawdziwych problemów. Na samym początku zdobędziesz elementarną wiedzę dotyczącą różnych typów dopasowania oraz dowiesz się, jak unikać najczęstszych problemów. Na kolejnych stronach nauczysz się stosować wyrażenia regularne w różnych językach programowania oraz wykorzystywać je do kontroli poprawności danych i formatowania ciągów znaków. Ponadto dowiesz się, jak operować na słowach, wierszach, znakach specjalnych oraz liczbach. Osobny rozdział został poświęcony operacjom na adresach URL oraz ścieżkach dostępu. Dzięki tej książce szybko zgłębisz tajniki wyrażeń regularnych. Kolejny krok to wykorzystanie tej wiedzy w codziennej pracy!

Sprawdź, jak wyrażenia regularne mogą przyśpieszyć Twoją pracę!

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

Darmowy fragment publikacji:

Wyra¿enia regularne. Receptury Autorzy: Jan Goyvaerts, Steven Levithan T³umaczenie: Miko³aj Szczepaniak ISBN: 978-83-246-2510-9 Tytu³ orygina³u: Regular Expressions Cookbook Format: 168×237, stron: 520 Poznaj i wykorzystaj mo¿liwoœci regexpów w codziennej pracy! (cid:129) Jak wyra¿enia regularne mog¹ przyœpieszyæ Twoj¹ pracê? (cid:129) Jak sprawdziæ poprawnoœæ danych? (cid:129) Jak wykorzystaæ wyra¿enia regularne w pracy z plikami XML? Wyra¿enie regularne (ang. regexp) to inaczej wzorzec, który okreœla zbiór dopasowanych ³añcuchów znaków. Brzmi to prosto. Jednak przy pierwszym spotkaniu z wyra¿eniami wcale tak nie jest. Zbiór znaków i symboli sk³adaj¹cy siê na wyra¿enie regularne w niczym nie przypomina rzeczy, któr¹ chcia³byœ siê zaj¹æ. Wyra¿enia regularne zawsze kojarz¹ siê pocz¹tkuj¹cemu u¿ytkownikowi co najmniej z wiedz¹ tajemn¹, a czêsto wrêcz z magi¹. Warto im siê jednak przyjrzeæ, poznaæ je i polubiæ, a nastêpnie wykorzystaæ mo¿liwoœci, jakie w nich drzemi¹. Jedno jest pewne – te mo¿liwoœci s¹ spore. Autorzy b³yskawicznie zaprzyjaŸni¹ Ciê z wyra¿eniami regularnymi – ksi¹¿ka nale¿y bowiem do znanej serii Receptury, cechuj¹cej siê tym, ¿e proces nauki jest oparty na analizie rozwi¹zañ prawdziwych problemów. Na samym pocz¹tku zdobêdziesz elementarn¹ wiedzê dotycz¹c¹ ró¿nych typów dopasowania oraz dowiesz siê, jak unikaæ najczêstszych problemów. Na kolejnych stronach nauczysz siê stosowaæ wyra¿enia regularne w ró¿nych jêzykach programowania oraz wykorzystywaæ je do kontroli poprawnoœci danych i formatowania ci¹gów znaków. Ponadto dowiesz siê, jak operowaæ na s³owach, wierszach, znakach specjalnych oraz liczbach. Osobny rozdzia³ zosta³ poœwiêcony operacjom na adresach URL oraz œcie¿kach dostêpu. Dziêki tej ksi¹¿ce szybko zg³êbisz tajniki wyra¿eñ regularnych. Kolejny krok to wykorzystanie tej wiedzy w codziennej pracy! (cid:129) Dopasowanie sta³ego tekstu (cid:129) Dopasowanie znaków niedrukowanych (cid:129) Dopasowania na pocz¹tku i koñcu wiersza (cid:129) Wyra¿enia regularne dla ca³ych wyrazów (cid:129) Wykorzystanie alternatywnych wyra¿eñ (cid:129) Grupowanie dopasowañ (cid:129) Eliminowanie nawrotów (cid:129) Sposoby komentowania wyra¿eñ (cid:129) Wyra¿enia regularne w jêzykach programowania (cid:129) Weryfikacja i formatowanie danych z wykorzystaniem wyra¿eñ regularnych (cid:129) Dopasowanie kompletnego wiersza (cid:129) Praca z liczbami (cid:129) Operacje na adresach URL, œcie¿kach i adresach internetowych (cid:129) Wykorzystanie wyra¿eñ regularnych w pracy z plikami XML SprawdŸ, jak wyra¿enia regularne mog¹ przyœpieszyæ Twoj¹ pracê! Spis treļci Przedmowa ...............................................................................................................................9 1. Wprowadzenie do wyraŜeħ regularnych ................................................................... 15 15 20 22 Definicja wyraĔeþ regularnych Przeszukiwanie i zastöpowanie tekstu z wykorzystaniem wyraĔeþ regularnych Narzödzia do pracy z wyraĔeniami regularnymi 2. Podstawowe techniki budowania wyraŜeħ regularnych .......................................... 41 42 2.1. Dopasowywanie staäego tekstu 44 2.2. Dopasowywanie znaków niedrukowanych 47 2.3. Dopasowywanie jednego z wielu znaków 51 2.4. Dopasowywanie dowolnego znaku 53 2.5. Dopasowywanie czegoĈ na poczñtku i (lub) koþcu wiersza 58 2.6. Dopasowywanie caäych wyrazów 61 2.7. Punkty kodowe, wäaĈciwoĈci, bloki i alfabety standardu Unicode 73 2.8. Dopasowywanie jednego z wielu alternatywnych wyraĔeþ 75 2.9. Grupowanie i przechwytywanie fragmentów dopasowaþ 78 2.10. Ponowne dopasowanie juĔ dopasowanego tekstu 80 2.11. Przechwytywanie i nazywanie fragmentów dopasowaþ 83 2.12. Powtarzanie fragmentu wyraĔenia regularnego okreĈlonñ liczbö razy 86 2.13. Wybieranie minimalnego lub maksymalnego z powtórzeþ 89 2.14. Eliminowanie niepotrzebnych nawrotów 92 2.15. Zapobieganie niekoþczñcym siö powtórzeniom 2.16. Testowanie dopasowaþ bez ich dodawania do wäaĈciwego dopasowania 95 2.17. Dopasowywanie jednej lub dwóch alternatyw zaleĔnie od pewnego warunku 102 2.18. Dodawanie komentarzy do wyraĔeþ regularnych 104 2.19. Umieszczanie staäego tekstu w tekĈcie docelowym operacji wyszukiwania i zastöpowania 106 2.20. Umieszczanie dopasowania wyraĔenia regularnego w tekĈcie docelowym operacji wyszukiwania i zastöpowania 109 3 2.21. Umieszczanie fragmentu wyraĔenia regularnego w tekĈcie docelowym operacji wyszukiwania i zastöpowania 2.22. Umieszczanie kontekstu dopasowania w tekĈcie docelowym operacji wyszukiwania i zastöpowania 111 114 3. Programowanie z wykorzystaniem wyraŜeħ regularnych .......................................117 117 123 129 131 137 Jözyki programowania i odmiany wyraĔeþ regularnych 3.1. Staäe wyraĔenia regularne w kodzie Ēródäowym 3.2. Importowanie biblioteki wyraĔeþ regularnych 3.3. Tworzenie obiektów wyraĔeþ regularnych 3.4. Ustawianie opcji wyraĔeþ regularnych 3.5. Sprawdzanie moĔliwoĈci odnalezienia dopasowania w przetwarzanym äaþcuchu 144 151 156 161 167 173 179 185 188 192 199 204 211 213 218 227 231 241 246 248 252 256 259 3.6. Sprawdzanie, czy dane wyraĔenie regularne pasuje do caäego przetwarzanego äaþcucha 3.7. Uzyskiwanie dopasowanego tekstu 3.8. OkreĈlanie pozycji i däugoĈci dopasowania 3.9. Uzyskiwanie czöĈci dopasowanego tekstu 3.10. Uzyskiwanie listy wszystkich dopasowaþ 3.11. Iteracyjne przeszukiwanie wszystkich dopasowaþ 3.12. Filtrowanie dopasowaþ w kodzie proceduralnym 3.13. Odnajdywanie dopasowania w ramach innego dopasowania 3.14. Zastöpowanie wszystkich dopasowaþ 3.15. Zastöpowanie dopasowaþ z wykorzystaniem ich fragmentów 3.16. Zastöpowanie dopasowaþ tekstem docelowym generowanym na poziomie kodu proceduralnego 3.17. Zastöpowanie wszystkich dopasowaþ w ramach dopasowaþ do innego wyraĔenia regularnego 3.18. Zastöpowanie wszystkich dopasowaþ pomiödzy dopasowaniami do innego wyraĔenia regularnego 3.19. Dzielenie äaþcucha 3.20. Dzielenie äaþcucha z zachowaniem dopasowaþ do wyraĔenia regularnego 3.21. Przeszukiwanie kolejnych wierszy 4. Weryfikacja i formatowanie danych ........................................................................235 235 4.1. Weryfikacja adresów poczty elektronicznej 4.2. Weryfikacja i formatowanie numerów telefonów stosowanych w Ameryce Póänocnej 4.3. Weryfikacja miödzynarodowych numerów telefonów 4.4. Weryfikacja tradycyjnych formatów zapisu daty 4.5. Bardziej restrykcyjna weryfikacja tradycyjnych formatów zapisu daty 4.6. Weryfikacja tradycyjnych formatów godziny 4.7. Weryfikacja zgodnoĈci daty i godziny ze standardem ISO 8601 4 _ Spis treļci 4.8. Ograniczanie danych wejĈciowych do znaków alfanumerycznych 4.9. Ograniczanie däugoĈci dopasowywanego tekstu 4.10. Ograniczanie liczby wierszy w przetwarzanym tekĈcie 4.11. Weryfikacja pozytywnych odpowiedzi 4.12. Weryfikacja numerów ubezpieczenia spoäecznego (SSN) stosowanych w Stanach Zjednoczonych 4.13. Weryfikacja numerów ISBN 4.14. Weryfikacja amerykaþskich kodów pocztowych 4.15. Weryfikacja kanadyjskich kodów pocztowych 4.16. Weryfikacja brytyjskich kodów pocztowych 4.17. Odnajdywanie adresów wskazujñcych skrytki pocztowe 4.18. Zmiana formatów nazwisk z „imiö nazwisko” na „nazwisko, imiö” 4.19. Weryfikacja numerów kart kredytowych 4.20. Europejskie numery päatników podatku VAT 263 266 270 275 277 279 286 287 288 288 290 293 299 5. Wyrazy, wiersze i znaki specjalne ............................................................................307 307 5.1. Odnajdywanie okreĈlonego wyrazu 310 5.2. Odnajdywanie dowolnego wyrazu ze zbioru säów 312 5.3. Odnajdywanie podobnych wyrazów 316 5.4. Odnajdywanie wszystkich wyrazów z wyjñtkiem okreĈlonego säowa 5.5. Odnajdywanie dowolnego säowa, po którym nie wystöpuje pewien wyraz 318 5.6. Odnajdywanie dowolnego säowa, przed którym nie wystöpuje pewien wyraz 319 323 5.7. Odnajdywanie wyrazów znajdujñcych siö w pobliĔu 5.8. Odnajdywanie powtarzajñcych siö wyrazów 329 330 5.9. Usuwanie powtarzajñcych siö wierszy 335 5.10. Dopasowywanie kompletnych wierszy zawierajñcych okreĈlony wyraz 337 5.11. Dopasowywanie kompletnych wierszy, które nie zawierajñ okreĈlonego säowa 5.12. Obcinanie poczñtkowych i koþcowych znaków biaäych 338 341 5.13. Zastöpowanie powtarzajñcych siö znaków biaäych pojedynczñ spacjñ 5.14. Stosowanie znaków ucieczki dla metaznaków wyraĔeþ regularnych 342 6. Liczby .........................................................................................................................347 347 350 353 354 355 361 364 367 368 6.1. Liczby caäkowite 6.2. Liczby szesnastkowe 6.3. Liczby binarne 6.4. Usuwanie poczñtkowych zer 6.5. Liczby naleĔñce do okreĈlonego przedziaäu 6.6. Liczby szesnastkowe naleĔñce do okreĈlonego przedziaäu 6.7. Liczby zmiennoprzecinkowe 6.8. Liczby z separatorem tysiñca 6.9. Liczby rzymskie Spis treļci _ 5 7. Adresy URL, ļcieŜki i adresy internetowe .................................................................371 371 375 377 378 380 381 383 388 390 392 394 396 399 400 401 403 406 418 421 425 426 427 430 431 432 7.1. Weryfikacja adresów URL 7.2. Odnajdywanie adresów URL w däuĔszym tekĈcie 7.3. Odnajdywanie w däuĔszym tekĈcie adresów URL otoczonych cudzysäowami 7.4. Odnajdywanie w däuĔszym tekĈcie adresów URL z nawiasami okrñgäymi 7.5. Umieszczanie adresów URL w äñczach 7.6. Weryfikacja nazw URN 7.7. Weryfikacja poprawnoĈci adresów URL wedäug ogólnych reguä 7.8. Wyodröbnianie schematu z adresu URL 7.9. Wyodröbnianie nazwy uĔytkownika z adresu URL 7.10. Wyodröbnianie nazwy hosta z adresu URL 7.11. Wyodröbnianie numeru portu z adresu URL 7.12. Wyodröbnianie ĈcieĔki z adresu URL 7.13. Wyodröbnianie zapytania z adresu URL 7.14. Wyodröbnianie fragmentu z adresu URL 7.15. Weryfikacja nazw domen 7.16. Dopasowywanie adresów IPv4 7.17. Dopasowywanie adresów IPv6 7.18. Weryfikacja ĈcieĔek systemu Windows 7.19. Dzielenie ĈcieĔek systemu Windows na czöĈci skäadowe 7.20. Wyodröbnianie litery dysku ze ĈcieĔki systemu Windows 7.21. Wyodröbnianie serwera i zasobu ze ĈcieĔki UNC 7.22. Wyodröbnianie folderu ze ĈcieĔki systemu operacyjnego Windows 7.23. Wyodröbnianie nazwy pliku ze ĈcieĔki systemu Windows 7.24. Wyodröbnianie rozszerzenia pliku ze ĈcieĔki systemu Windows 7.25. Usuwanie nieprawidäowych znaków z nazw plików 8. Jýzyki znaczników i formaty wymiany danych ........................................................435 441 8.1. Odnajdywanie znaczników XML-a 8.2. Zastöpowanie znaczników b znacznikami strong 459 8.3. Usuwanie wszystkich znaczników XML-a z wyjñtkiem znaczników em i strong 8.4. Dopasowywanie nazw XML-a 8.5. Konwersja zwykäego tekstu na kod HTML-a poprzez dodanie znaczników p i br 8.6. Odnajdywanie konkretnych atrybutów w znacznikach XML-a 8.7. Dodawanie atrybutu cellspacing do tych znaczników table , które jeszcze tego atrybutu nie zawierajñ 8.8. Usuwanie komentarzy XML-a 8.9. Odnajdywanie säów w ramach komentarzy XML-a 8.10. Zmiana separatora stosowanego w plikach CSV 462 465 471 475 479 482 486 491 6 _ Spis treļci 8.11. Wyodröbnianie pól CSV z okreĈlonej kolumny 8.12. Dopasowywanie nagäówków sekcji pliku INI 8.13. Dopasowywanie bloków sekcji pliku INI 8.14. Dopasowywanie par nazwa-wartoĈè w plikach INI 494 498 499 501 Skorowidz .............................................................................................................................503 Spis treļci _ 7 ROZDZIAĤ 3. Programowanie z wykorzystaniem wyraŜeħ regularnych Jýzyki programowania i odmiany wyraŜeħ regularnych W tym rozdziale wyjaĈnimy, jak implementowaè wyraĔenia regularne w wybranym przez Ciebie jözyku programowania. W recepturach skäadajñcych siö na ten rozdziaä zakäadamy, Ĕe dyspo- nujesz juĔ prawidäowymi wyraĔeniami regularnymi (w ich konstruowaniu powinny Ci pomóc poprzednie rozdziaäy). Koncentrujemy siö wiöc tylko na zadaniu umieszczania wyraĔeþ regu- larnych w kodzie Ēródäowym i wykorzystywaniu ich do wäaĈciwego dziaäania. W tym rozdziale robimy, co w naszej mocy, aby moĔliwie precyzyjnie wyjaĈniè, jak i dlaczego poszczególne fragmenty kodu dziaäajñ w ten czy inny sposób. WäaĈnie z uwagi na wysoki poziom szczegóäowoĈci czytanie tego rozdziaäu od poczñtku do koþca moĔe byè doĈè nuĔñce. JeĈli czytasz tö ksiñĔkö po raz pierwszy, zachöcamy tylko do przejrzenia tego rozdziaäu, aby dysponowaè ogólnñ wiedzñ o tym, co jest moĔliwe, a co jest konieczne. W przyszäoĈci, kiedy bödziesz implementowaä wyraĔenia regularne proponowane w kolejnych rozdziaäach, bödziesz mógä wróciè do tego materiaäu, aby dokäadnie dowiedzieè siö, jak integrowaè te wyraĔenia z wybranym jözykiem programowania. W rozdziaäach 4. – 8. bödziemy wykorzystywali wyraĔenia regularne do rozwiñzywania rzeczy- wistych problemów programistycznych. W tych piöciu rozdziaäach bödziemy koncentrowali siö na samych wyraĔeniach regularnych, a wiele receptur w ogóle nie bödzie zawieraäo kodu Ēródäowego. Aby wyraĔenia prezentowane w tych rozdziaäach mogäy byè stosowane w praktyce, naleĔy je przenieĈè do fragmentów kodu Ēródäowego z niniejszego rozdziaäu. PoniewaĔ w pozostaäych rozdziaäach koncentrujemy siö na wyraĔeniach regularnych, prezen- tujemy rozwiñzania dla konkretnych odmian wyraĔeþ regularnych zamiast dla poszczegól- nych jözyków programowania. Odmiany wyraĔeþ regularnych nie sñ zwiñzane relacjñ jeden do jednego z odpowiednimi jözykami programowania. Jözyki skryptowe zwykle oferujñ wäa- sne, wbudowane odmiany wyraĔeþ regularnych, a pozostaäe jözyki programowania najczö- Ĉciej korzystajñ z odpowiednich bibliotek. Niektóre z tych bibliotek sñ dostöpne w wersjach dla wielu jözyków programowania, a czöĈè jözyków oferuje swoim programistom wiöcej niĔ jednñ bibliotekö. 117 W punkcie „RóĔne odmiany wyraĔeþ regularnych” w rozdziale 1. opisano wszystkie odmiany wyraĔeþ regularnych prezentowanych w tej ksiñĔce. W punkcie „Zastöpowanie tekstu w róĔ- nych odmianach” takĔe w rozdziale 1. wymieniono odmiany zastöpowania tekstu stosowane podczas operacji przeszukiwania i zastöpowania danych z wykorzystaniem wyraĔeþ regular- nych. Wszystkie jözyki programowania omawiane w tym rozdziale korzystajñ z jednej z tych odmian. Jýzyki programowania omawiane w tym rozdziale W tym rozdziale omówimy siedem jözyków programowania. KaĔda receptura zawiera odröbne rozwiñzania dla wszystkich oĈmiu jözyków programowania, a w wielu recepturach sporzñ- dzono nawet osobne analizy rozwiñzaþ pod kñtem poszczególnych jözyków. JeĈli jakaĈ tech- nika ma zastosowanie w wiöcej niĔ jednym jözyku, wspominamy o niej w analizie dla kaĔdego z tych jözyków. ZdecydowaliĈmy siö na takie rozwiñzanie, abyĈ mógä bezpiecznie pomijaè jözyki programowania, którymi nie jesteĈ zainteresowany. C# Jözyk programowania C# korzysta z frameworku Microsoft .NET. Klasy przestrzeni nazw System.Text.RegularExpressions stosujñ wiöc odmianö wyraĔeþ regularnych i zastö- powania tekstu, które w tej ksiñĔce nazywamy odmianami platformy .NET. W tej ksiñĔce omówimy jözyk C# w wersjach od 1.0 do 3.5 (stosowane odpowiednio w Ĉrodowiskach Visual Studio od wersji 2002 do wersji 2008). VB.NET W tej ksiñĔce bödziemy uĔywali terminów VB.NET i Visual Basic.NET w kontekĈcie jözyka programowania Visual Basic 2002 i nowszych, aby uniknñè mylenia tych wersji z jözykiem Visual Basic 6 i starszymi. Wspóäczesne wersje Visual Basica korzystajñ z frameworku Microsoft .NET. Wspomniana juĔ przestrzeþ nazw System.Text.RegularExpressions implementuje odmianö wyraĔeþ regularnych i zastöpowania tekstu, które w tej ksiñĔce nazywamy odmianami platformy .NET. W tej ksiñĔce ograniczymy siö do prezentacji jözyka Visual Basic w wersjach 2002 – 2008. Java Java 4 jest pierwszym wydaniem oferujñcym wbudowanñ obsäugö wyraĔeþ regularnych w formie pakietu java.util.regex. WäaĈnie pakiet java.util.regex implementuje odmianö wyraĔeþ regularnych i zastöpowanego tekstu, które w tej ksiñĔce nazywamy odmianñ Javy. W tej ksiñĔce omawiamy Javö 4, 5 i 6. JavaScript Tö odmianö wyraĔeþ regularnych stosuje siö w jözyku programowania powszechnie zna- nym jako JavaScript. Wspomniany jözyk jest implementowany przez wszystkie wspóä- czesne przeglñdarki internetowe: Internet Explorer (przynajmniej w wersji 5.5), Firefox, Opera, Safari oraz Chrome. TakĔe wiele innych aplikacji wykorzystuje JavaScript w roli jözyka skryptowego. Precyzyjnie mówiñc, w tej ksiñĔce bödziemy uĔywali terminu JavaScript w kontekĈcie jözyka programowania zdefiniowanego w trzeciej wersji standardu ECMA-262. Wspomniany stan- dard definiuje jözyk programowania ECMAScript znany lepiej dziöki implementacjom nazwanym JavaScript i JScript, oferowanym w rozmaitych przeglñdarkach internetowych. 118 _ Rozdziaĥ 3. Programowanie z wykorzystaniem wyraŜeħ regularnych Standard ECMA-262v3 definiuje teĔ stosowane w JavaScripcie odmiany wyraĔeþ regular- nych i zastöpowanego tekstu. W tej ksiñĔce bödziemy okreĈlali te odmiany mianem odmian JavaScriptu. PHP PHP oferuje trzy zbiory funkcji operujñcych na wyraĔeniach regularnych. PoniewaĔ sami jesteĈmy zwolennikami korzystania z rodziny funkcji preg, w tej ksiñĔce bödziemy koncen- trowali siö wäaĈnie na nich (dostöpnych poczñwszy od wydania PHP 4.2.0). W tej ksiñĔce omówimy jözyk PHP 4 i 5. Funkcje z rodziny preg sñ w istocie opakowaniami funkcji biblio- teki PCRE. Odmianö wyraĔeþ regularnych implementowanñ przez tö bibliotekö bödziemy nazywali odmianñ PCRE. PoniewaĔ jednak biblioteka PCRE nie oferuje funkcji przeszu- kiwania i zastöpowania, twórcy jözyka PHP opracowali wäasnñ skäadniö zastöpowanego tekstu na potrzeby funkcji preg_replace. Samñ odmianö zastöpowanego tekstu nazywamy w tej ksiñĔce odmianñ PHP. Funkcje z rodziny mb_ereg wchodzñ w skäad zbioru tzw. funkcji wielobajtowych jözyka PHP, które zaprojektowano z myĈlñ o jözykach tradycyjnie kodowanych za pomocñ wielobaj- towych zbiorów znaków, na przykäad o jözykach japoþskim i chiþskim. W PHP 5 funkcje mb_ereg korzystajñ z biblioteki wyraĔeþ regularnych Oniguruma, którñ poczñtkowo two- rzono dla jözyka programowania Ruby. Odmianö wyraĔeþ regularnych zaimplemento- wanñ w bibliotece Oniguruma bödziemy nazywali odmianñ jözyka Ruby 1.9. Stosowanie funkcji z rodziny mb_ereg zaleca siö tylko tym programistom, którzy muszñ operowaè na wielobajtowych stronach kodowych i którzy opanowali juĔ techniki korzystania z funkcji mb_. Grupa funkcji ereg to najstarszy zbiór funkcji PHP stworzonych z myĈlñ o przetwarzaniu wyraĔeþ regularnych. Funkcje z tego zbioru oficjalnie uznano za przestarzaäe i niezalecane wraz z wydaniem PHP 5.3.0. Funkcje ereg nie korzystajñ z Ĕadnych bibliotek zewnötrz- nych i implementujñ odmianö POSIX ERE. Wspomniana odmiana oferuje jednak doĈè ograniczony zakres funkcji i jako taka nie jest omawiana w tej ksiñĔce. Funkcje odmiany POSIX ERE stanowiñ podzbiór funkcji oferowanych przez odmiany jözyka Ruby 1.9 i biblio- teki PCRE. KaĔde wyraĔenie regularne obsäugiwane przez funkcje ereg jest obsäugiwane takĔe przez funkcje z rodziny mb_ereg lub preg. Funkcje preg wymagajñ jednak stosowa- nia separatorów Perla (patrz receptura 3.1). Perl Wbudowana obsäuga wyraĔeþ regularnych Perla to jeden z gäównych powodów obser- wowanej obecnie popularnoĈci tych wyraĔeþ. Odmiany wyraĔeþ regularnych i zastöpowa- nego tekstu wykorzystywane przez operatory m// i s/// jözyka Perl nazywamy w tej ksiñĔce odmianami Perla. Skoncentrujemy siö na wersjach 5.6, 5.8 i 5.10. Python W jözyku Python obsäugö wyraĔeþ regularnych zaimplementowano w module re. W tej ksiñĔce odmiany wyraĔeþ regularnych i zastöpowanego tekstu nazywamy odmianami Pythona. W ksiñĔce omawiamy jözyk Python w wersjach 2.4 i 2.5. Ruby Jözyk Ruby oferuje wbudowanñ obsäugö wyraĔeþ regularnych. W tej ksiñĔce omówimy wersje 1.8 i 1.9 tego jözyka. Wymienione wersje jözyka Ruby domyĈlnie stosujñ róĔne moduäy wyraĔeþ regularnych. Jözyk Ruby 1.9 korzysta z moduäu Oniguruma, który ofe- ruje nieporównanie wiöcej funkcji niĔ klasyczny silnik stosowany w domyĈlnej kompilacji jözyka 1.8. Szczegóäowych informacji na ten temat naleĔy szukaè w punkcie „Odmiany wyra- Ĕeþ regularnych prezentowane w tej ksiñĔce” w rozdziale 1. Jýzyki programowania i odmiany wyraŜeħ regularnych _ 119 W tym rozdziale nie bödziemy poĈwiöcaè zbyt wiele uwagi róĔnicom dzielñcym moduäy wyraĔeþ regularnych wersji 1.8 i 1.9. WyraĔenia prezentowane w tym rozdziale bödñ na tyle proste, Ĕe nie bödñ potrzebne nowe funkcje zaimplementowane w jözyku Ruby 1.9. PoniewaĔ mechanizmy odpowiedzialne za obsäugö wyraĔeþ regularnych sñ wäñczane do samego jözyka Ruby na etapie kompilacji, kod wykorzystywany do implementowania wyra- Ĕeþ regularnych jest taki sam niezaleĔnie od wybranego moduäu (klasycznego lub biblioteki Oniguruma). Oznacza to, Ĕe istnieje moĔliwoĈè ponownej kompilacji jözyka Ruby 1.8, aby korzystaä z biblioteki Oniguruma (jeĈli na przykäad potrzebujemy rozszerzonych funkcji tej biblioteki). Inne jýzyki programowania Jözyki programowania wymienione na poniĔszej liĈcie nie bödñ omawiane w tej ksiñĔce, mimo Ĕe korzystajñ z prezentowanych przez nas odmian wyraĔeþ regularnych. JeĈli pracujesz w któ- rymĈ z tych jözyków, moĔesz pominñè ten rozdziaä i jednoczeĈnie z powodzeniem korzystaè z materiaäu zawartego w pozostaäych rozdziaäach. ActionScript ActionScript jest implementacjñ standardu ECMA-262 opracowanñ przez firmö Adobe. W wersji 3.0 jözyk ActionScript zawiera peänñ obsäugö wyraĔeþ regularnych zdefiniowa- nych w standardzie ECMA-262v3. W tej ksiñĔce bödziemy nazywali tö odmianö odmianñ JavaScriptu. Jözyk ActionScript jest bardzo podobny do jözyka JavaScript, zatem przenie- sienie fragmentów kodu JavaScriptu do jözyka ActionScript nie powinno Ci sprawiè naj- mniejszego problemu. C ProgramiĈci jözyka C majñ do dyspozycji wiele róĔnych bibliotek wyraĔeþ regularnych. Biblioteka PCRE typu open source jest bodaj najlepszym rozwiñzaniem tego typu spo- Ĉród wszystkich odmian omówionych w tej ksiñĔce. Kompletny kod Ēródäowy tej biblio- teki (w jözyku C) moĔna pobraè z witryny internetowej http://www.pcre.org. Kod napisano w taki sposób, aby umoĔliwiè jego kompilacjö z wykorzystaniem rozmaitych kompilatorów dla wielu róĔnych platform. C++ TakĔe programiĈci jözyka C++ majñ do wyboru wiele róĔnych bibliotek wyraĔeþ regu- larnych. Biblioteka PCRE typu open source jest bodaj najlepszym rozwiñzaniem tego typu spoĈród wszystkich odmian omówionych w tej ksiñĔce. Istnieje moĔliwoĈè korzystania albo bezpoĈrednio z interfejsu API jözyka C, albo z opakowaþ w formie klas jözyka C++ dostöpnych wraz z samñ bibliotekñ PCRE (patrz witryna internetowa http://www.pcre.org). W systemie Windows moĔna dodatkowo zaimportowaè obiekt COM nazwany VBScript 5.5 RegExp (patrz materiaä poĈwiöcony jözykowi Visual Basic 6). Takie rozwiñzanie jest korzystne, jeĈli chcemy zachowaè spójnoĈè wewnötrznych mechanizmów zaimplemento- wanych w C++ i elementów interfejsu zaimplementowanych w JavaScripcie. Delphi dla platformy Win32 W czasie, kiedy pisano tö ksiñĔkö, wersja jözyka Delphi dla platformy Win32 nie ofero- waäa Ĕadnych wbudowanych mechanizmów obsäugi wyraĔeþ regularnych. Istnieje jednak wiele komponentów VCL implementujñcych obsäugö wyraĔeþ regularnych. Sami polecamy wybór komponentu stworzonego na bazie biblioteki PCRE. Delphi oferuje moĔliwoĈè 120 _ Rozdziaĥ 3. Programowanie z wykorzystaniem wyraŜeħ regularnych doäñczania do budowanych aplikacji plików wynikowych jözyka C — wiökszoĈè opako- waþ biblioteki PCRE w formie komponentów VCL ma postaè wäaĈnie takich plików wyni- kowych. Takie rozwiñzanie umoĔliwia umieszczanie aplikacji w pojedynczych plikach .exe. Komponent nazwany TPerlRegEx (mojego autorstwa) moĔna pobraè ze strony interne- towej http://www.regexp.info/delphi.html. TPerlRegEx ma postaè komponentu VCL instalo- wanego automatycznie w palecie komponentów, zatem jego przeciñganie na formularz nie stanowi Ĕadnego problemu. Innym popularnym opakowaniem biblioteki PCRE dla Delphi jest klasa TJclRegEx wchodzñca w skäad biblioteki JCL (dostöpnej pod adresem http://www. delphi-jedi.org). PoniewaĔ jednak TJclRegEx jest klasñ potomnñ klasy TObject, nie jest moĔ- liwe jej przenoszenie na formularz. Obie biblioteki majñ charakter oprogramowania open source i sñ oferowane na zasadach licencji Mozilla Public License. Delphi Prism W Delphi Prism moĔna wykorzystaè mechanizm obsäugi wyraĔeþ regularnych zaimple- mentowany w ramach frameworku .NET. Wystarczy do klauzuli uses dodaè przestrzeþ nazw System.Text.RegularExpressions, aby dana jednostka jözyka Delphi Prism mogäa korzystaè ze wspomnianej implementacji wyraĔeþ regularnych. Po wykonaniu tego kroku moĔna z powodzeniem stosowaè te same techniki, które w tym rozdziale proponujemy dla jözyków C# i VB.NET. Groovy Podobnie jak w Javie, w jözyku Groovy do obsäugi wyraĔeþ regularnych moĔna wyko- rzystaè pakiet java.util.regex. W praktyce wszystkie prezentowane w tym rozdziale rozwiñzania dla Javy powinny dziaäaè prawidäowo takĔe w jözyku Groovy. Skäadnia wyra- Ĕeþ regularnych tego jözyka róĔni siö tylko dodatkowymi skrótami notacji. Staäe wyraĔenie regularne otoczone prawymi ukoĈnikami jest traktowane jako obiekt klasy java.lang. ´String, a operator =~ tworzy obiekt klasy java.util.regex.Matcher. MoĔemy swo- bodnie mieszaè skäadniö jözyka Groovy ze standardowñ skäadniñ Javy, poniewaĔ w obu przypadkach korzystamy z tych samych klas i obiektów. PowerShell PowerShell jest jözykiem skryptowym firmy Microsoft zaprojektowanym na bazie frame- worku .NET. Wbudowane operatory -match i -replace tego jözyka korzystajñ z odmian wyraĔeþ regularnych i zastöpowanego tekstu platformy .NET, czyli z odmian prezentowa- nych w tej ksiñĔce. R W projekcie R zaimplementowano obsäugö wyraĔeþ regularnych za poĈrednictwem funkcji grep, sub i regexpr pakietu base. Wszystkie te funkcje otrzymujñ na wejĈciu argu- ment oznaczony etykietñ perl, który — w razie pominiöcia — ma przypisywanñ wartoĈè FALSE. JeĈli za poĈrednictwem tego argumentu przekaĔemy wartoĈè TRUE, wymusimy uĔycie opisanej w tej ksiñĔce odmiany wyraĔeþ regularnych biblioteki PCRE. WyraĔenia regularne tworzone z myĈlñ o bibliotece PCRE 7 mogñ byè z powodzeniem stosowane w jözyku R, poczñwszy od wersji 2.5.0. W starszych wersjach tego jözyka naleĔy stosowaè wyraĔenia regularne, które w tej ksiñĔce opisujemy jako tworzone z myĈlñ o bibliotece PCRE 4 lub nowszych. Obsäugiwane w jözyku R odmiany „podstawowa” i „rozszerzona”, które sñ starsze i mocno ograniczone, nie bödñ omawiane w tej ksiñĔce. Jýzyki programowania i odmiany wyraŜeħ regularnych _ 121 REALbasic Jözyk REALbasic oferuje wbudowanñ klasö RegEx. Wspomniana klasa wewnötrznie wyko- rzystuje bibliotekö PCRE w wersji przystosowanej do pracy z formatem UTF-8. Oznacza to, Ĕe istnieje moĔliwoĈè korzystania z biblioteki PCRE w wersji z obsäugñ standardu Unicode, jednak konwersja znaków spoza zbioru ASCII na znaki UTF-8 (przed przekazaniem do klasy RegEx) wymaga uĔycia klasy TextConverter jözyka REALbasic. Wszystkie prezentowane w tej ksiñĔce wyraĔenia regularne dla biblioteki PCRE 6 moĔna z powodzeniem stosowaè takĔe w jözyku REALbasic. Warto jednak pamiötaè, Ĕe w tym jözyku opcje ignorowania wielkoĈci liter i dopasowywania znaków podziaäu wiersza do karety i dolara (tzw. tryb wielowierszowy) sñ domyĈlnie wäñczone. Oznacza to, Ĕe jeĈli chcesz uĔywaè w jözyku REALbasic wyraĔeþ regularnych, które nie wymagajñ wäñczenia tych trybów dopasowywania, powinieneĈ je wprost wyäñczyè. Scala Jözyk Scala oferuje wbudowanñ obsäugö wyraĔeþ regularnych w formie pakietu scala. ´util.matching. Pakiet ten zaprojektowano na podstawie moduäu wyraĔeþ regularnych stosowanego w Javie (czyli pakietu java.util.regex). Odmiany wyraĔeþ regularnych i zastöpowanego tekstu obowiñzujñce w jözykach Java i Scala nazywamy w tej ksiñĔce po prostu odmianami Javy. Visual Basic 6 Visual Basic 6 byä ostatniñ wersjñ tego jözyka, która nie wymagaäa frameworku .NET. Ozna- cza to, Ĕe programiĈci korzystajñcy z tej wersji nie dysponujñ doskonaäymi mechanizmami obsäugi wyraĔeþ regularnych tego frameworku. Przykäadów kodu jözyka VB.NET prezen- towanych w tym rozdziale nie moĔna wiöc przenosiè do jözyka VB 6. Z drugiej strony Visual Basic 6 znacznie uäatwia korzystanie z funkcji implementowanych przez biblioteki ActiveX i COM. Jednym z takich rozwiñzaþ jest biblioteka skryptowa VBScript firmy Microsoft. Poczñwszy od wersji 5.5, w bibliotece VBScript implemento- wano uproszczonñ obsäugö wyraĔeþ regularnych. Wspomniana biblioteka skryptowa imple- mentuje tö samñ odmianö wyraĔeþ regularnych, która jest stosowana w JavaScripcie (zgodnñ ze standardem ECMA-262v3). Biblioteka VBScript jest czöĈciñ przeglñdarki Internet Explo- rer 5.5 i nowszych, zatem jest dostöpna na wszystkich komputerach z systemem opera- cyjnym Windows XP lub Windows Vista (oraz starszymi systemami operacyjnymi, jeĈli tylko ich uĔytkownicy zaktualizowali przeglñdarkö do wersji 5.5 lub nowszej). Oznacza to, Ĕe biblioteka VBScript jest dostöpna na praktycznie wszystkich komputerach z systemem Windows wykorzystywanych do äñczenia siö z internetem. Aby uĔyè tej biblioteki w aplikacji tworzonej w Visual Basicu, z menu Project zintegrowa- nego Ĉrodowiska programowania (IDE) naleĔy wybraè opcjö References. Na wyĈwietlonej liĈcie powinieneĈ odnaleĒè pozycjö Microsoft VBScript Regular Expressions 5.5 (dostöpnñ bezpoĈrednio pod pozycjñ Microsoft VBScript Regular Expressions 1.0). Upewnij siö, Ĕe na liĈcie jest zaznaczona wersja 5.5, nie wersja 1.0. Wersja 1.0 ma na celu wyäñcznie zapewnie- nie zgodnoĈci wstecz, a jej moĔliwoĈci sñ dalekie od satysfakcjonujñcych. Po dodaniu tej referencji uzyskujesz dostöp do wykazu klas i skäadowych klas wchodzñ- cych w skäad wybranej biblioteki. Warto teraz wybraè z menu View opcjö Object Browser. Z listy rozwijanej w lewym górnym rogu okna Object Browser wybierz z bibliotekö VBScript_ RegExp_55. 122 _ Rozdziaĥ 3. Programowanie z wykorzystaniem wyraŜeħ regularnych 3.1. Staĥe wyraŜenia regularne w kodzie Śródĥowym Problem OtrzymaäeĈ wyraĔenie regularne [$ \n\d/\\] jako rozwiñzanie pewnego problemu. Wyra- Ĕenie to skäada siö z pojedynczej klasy znaków pasujñcej do znaku dolara, cudzysäowu, apo- strofu, znaku nowego wiersza, dowolnej cyfry (0 – 9) oraz prawego i lewego ukoĈnika. Twoim zadaniem jest trwaäe zapisanie tego wyraĔenia regularnego w kodzie Ēródäowym (w formie staäej äaþcuchowej lub operatora wyraĔenia regularnego). Rozwiézanie C# W formie zwykäego äaþcucha: [$\ \n\\d/\\\\] W formie äaþcucha dosäownego: @ [$ \n\d/\\] VB.NET [$ \n\d/\\] Java [$\ \n\\d/\\\\] JavaScript /[$ \n\d\/\\]/ PHP [$ \ \n\d/\\\\] Perl Operator dopasowywania wzorców: /[\$ \n\d\/\\]/ m![\$ \n\d/\\]! Operator podstawiania: s![\$ \n\d/\\]!! Python Standardowy (surowy) äaþcuch otoczony potrójnymi cudzysäowami: r [$ \n\d/\\] 3.1. Staĥe wyraŜenia regularne w kodzie Śródĥowym _ 123 Zwykäy äaþcuch: [$\ \n\\d/\\\\] Ruby Staäe wyraĔenie regularne otoczone prawymi ukoĈnikami: /[$ \n\d\/\\]/ Staäe wyraĔenie regularne otoczone wybranymi znakami interpunkcyjnymi: r![$ \n\d/\\]! Analiza Kiedy w tej ksiñĔce proponujemy Ci samo wyraĔenie regularne (czyli wyraĔenie niebödñce czöĈciñ wiökszego fragmentu kodu Ēródäowego), zawsze formatujemy je w standardowy sposób. Ta receptura jest jedynym wyjñtkiem od tej reguäy. JeĈli korzystasz z testera wyraĔeþ regularnych, jak RegexBuddy czy RegexPal, powinieneĈ wpisywaè swoje wyraĔenia wäaĈnie w ten sposób. JeĈli Twoja aplikacja operuje na wyraĔeniach regularnych wpisywanych przez uĔytkownika, takĔe uĔytkownik powinien wpisywaè swoje wyraĔenia w ten sposób. JeĈli jednak chcesz zapisywaè staäe wyraĔenia regularne w swoim kodzie Ēródäowym, musisz siö liczyè z dodatkowymi zadaniami. BezmyĈlne, nieostroĔne kopiowanie i wklejanie wyraĔeþ regularnych z testera do kodu Ēródäowego (i w przeciwnym kierunku) czösto prowadziäoby do bäödów, a Ciebie zmuszaäoby do gruntownych analiz obserwowanych zjawisk. MusiaäbyĈ poĈwiöciè sporo czasu na odkrywanie, dlaczego to samo wyraĔenie regularne dziaäa w testerze, ale nie dziaäa w kodzie Ēródäowym, lub nie dziaäa w testerze, mimo Ĕe zostaäo skopiowane z prawidäowego kodu Ēródäowego. Wszystkie jözyki programowania omawiane w tej ksiñĔce wymagajñ otaczania staäych wyraĔeþ regularnych okreĈlonymi separatorami — czöĈè jözy- ków korzysta ze skäadni äaþcuchów, inne wprowadzajñ specjalnñ skäadniö staäych wyraĔeþ regularnych. JeĈli Twoje wyraĔenie regularne zawiera separatory danego jözyka programo- wania lub inne znaki, które majñ w tym jözyku jakieĈ specjalne znaczenie, musisz zastosowaè sekwencje ucieczki. NajczöĈciej stosowanym symbolem ucieczki jest lewy ukoĈnik (\). WäaĈnie dlatego wiökszoĈè rozwiñzaþ zaproponowanych dla tego problemu zawiera duĔo wiöcej lewych ukoĈników niĔ cztery ukoĈniki z oryginalnego wyraĔenia regularnego (w punkcie „Problem”). C# W jözyku C# wyraĔenia regularne moĔna przekazywaè na wejĈciu konstruktora Regex() i roz- maitych funkcji skäadowych klasy Regex. Parametry reprezentujñce wyraĔenia regularne zawsze sñ deklarowane jako äaþcuchy. C# obsäuguje dwa rodzaje staäych äaþcuchowych. Najbardziej popularnym rodzajem takich staäych sñ äaþcuchy otoczone cudzysäowami, czyli konstrukcje doskonale znane z takich jözy- ków programowania, jak C++ czy Java. W ramach äaþcuchów otoczonych cudzysäowami inne cudzysäowy i lewe ukoĈniki muszñ byè poprzedzane lewymi ukoĈnikami. W äaþcuchach moĔna teĔ stosowaè sekwencje ucieczki ze znakami niedrukowanymi, na przykäad \n . JeĈli wäñ- czono tryb swobodnego stosowania znaków biaäych (patrz receptura 2.18) za poĈrednictwem 124 _ Rozdziaĥ 3. Programowanie z wykorzystaniem wyraŜeħ regularnych RegexOptions.IgnorePatternWhitespace, konstrukcje \n i \\n sñ traktowane w odmienny sposób (patrz receptura 3.4). O ile konstrukcja \n jest traktowana jako staäa äaþcuchowa z podziaäem wiersza, która nie pasuje do znaków biaäych, o tyle \\n jest äaþcuchem z toke- nem wyraĔenia regularnego \n , który pasuje do nowego wiersza. Tzw. äaþcuchy dosäowne (ang. verbatim strings) rozpoczynajñ siö od znaku @ i cudzysäowu, a koþczñ siö samym cudzysäowem. Umieszczenie cudzysäowu w äaþcuchu dosäownym wymaga uĔycia dwóch nastöpujñcych po sobie cudzysäowów. W ramach tego rodzaju äaþcuchów nie trzeba jednak stosowaè sekwencji ucieczki dla lewych ukoĈników, co znacznie poprawia czy- telnoĈè wyraĔeþ regularnych. Konstrukcja @ \n zawsze reprezentuje token wyraĔenia regu- larnego \n , który pasuje do znaku nowego wiersza (takĔe w trybie swobodnego stosowa- nia znaków biaäych). ãaþcuchy dosäowne co prawda nie obsäugujñ tokenu \n na poziomie samych äaþcuchów, ale mogñ obejmowaè wiele wierszy. Konstrukcje äaþcuchów dosäownych wprost idealnie nadajñ siö wiöc do zapisywania wyraĔeþ regularnych. Wybór jest doĈè prosty — najlepszym sposobem zapisywania wyraĔeþ regularnych w kodzie Ēródäowym jözyka C# jest stosowanie äaþcuchów dosäownych. VB.NET W jözyku VB.NET istnieje moĔliwoĈè przekazywania staäych wyraĔeþ na wejĈciu konstruktora Regex() oraz rozmaitych funkcji skäadowych klasy Regex. Parametr reprezentujñcy wyraĔenie regularne zawsze jest deklarowany jako äaþcuch. W Visual Basicu stosuje siö äaþcuchy otoczone cudzysäowami. Cudzysäowy w ramach tych äaþcuchów naleĔy zapisywaè podwójnie. ēadne inne znaki nie wymagajñ stosowania sekwencji ucieczki. Java W Javie staäe wyraĔenia regularne moĔna przekazywaè na wejĈciu fabryki (wytwórni) klas Pattern.compile() oraz rozmaitych funkcji klasy String. Parametry reprezentujñce wyraĔe- nia regularne zawsze deklaruje siö jako äaþcuchy. W Javie äaþcuchy otacza siö cudzysäowami. Ewentualne cudzysäowy i lewe ukoĈniki w ramach tych äaþcuchów naleĔy poprzedzaè symbolem ucieczki, czyli lewym ukoĈnikiem. W äaþcu- chach moĔna teĔ umieszczaè znaki niedrukowane (na przykäad \n ) oraz sekwencje ucieczki standardu Unicode (na przykäad \uFFFF ). JeĈli wäñczono tryb swobodnego stosowania znaków biaäych (patrz receptura 2.18) za poĈred- nictwem Pattern.COMMENTS, konstrukcje \n i \\n sñ traktowane w odmienny sposób (patrz receptura 3.4). O ile konstrukcja \n jest interpretowana jako staäa äaþcuchowa z podzia- äem wiersza, która nie pasuje do znaków biaäych, o tyle \\n jest äaþcuchem z tokenem wyra- Ĕenia regularnego \n , który pasuje do nowego wiersza. JavaScript W JavaScripcie najlepszym sposobem tworzenia wyraĔeþ regularnych jest korzystanie ze skäadni zaprojektowanej specjalnie z myĈlñ o deklarowaniu staäych wyraĔeþ regularnych. Wystarczy umieĈciè wyraĔenie regularne pomiödzy dwoma prawymi ukoĈnikami. JeĈli samo wyraĔenie zawiera prawe ukoĈniki, naleĔy kaĔdy z nich poprzedziè lewym ukoĈnikiem. 3.1. Staĥe wyraŜenia regularne w kodzie Śródĥowym _ 125 Mimo Ĕe istnieje moĔliwoĈè tworzenia obiektów klasy RegExp na podstawie äaþcuchów, sto- sowanie notacji äaþcuchowej dla staäych wyraĔeþ regularnych definiowanych w kodzie Ēró- däowym nie miaäoby wiökszego sensu, poniewaĔ wymagaäoby stosowania sekwencji ucieczki dla cudzysäowów i lewych ukoĈników (co zwykle prowadzi do powstania prawdziwego gñszczu lewych ukoĈników). PHP Staäe wyraĔenia regularne na potrzeby funkcji preg jözyka PHP sñ przykäadem doĈè niety- powego rozwiñzania. Inaczej niĔ Java czy Perl, PHP nie definiuje rdzennego typu wyraĔeþ regularnych. Podobnie jak äaþcuchy, wyraĔenia regularne zawsze muszñ byè otoczone apo- strofami. Dotyczy to takĔe funkcji ze zbiorów ereg i mb_ereg. Okazuje siö jednak, Ĕe w swoich dñĔeniach do powielenia rozwiñzaþ znanych z Perla twórcy funkcji-opakowaþ biblioteki PCRE dla jözyka PHP wprowadzili pewne dodatkowe wymaganie. WyraĔenie regularne umieszczone w äaþcuchu musi byè dodatkowo otoczone separatorami stosowanymi dla staäych wyraĔeþ regularnych Perla. Oznacza to, Ĕe wyraĔenie regularne, które w Perlu miaäoby postaè /wyrašenie/, w jözyku PHP (stosowane na wejĈciu funkcji preg) musiaäoby mieè postaè /wyrašenie/ . Podobnie jak w Perlu, istnieje moĔliwoĈè wykorzy- stywania w roli separatorów par dowolnych znaków interpunkcyjnych. JeĈli jednak separator danego wyraĔenia regularnego wystöpuje w ramach tego wyraĔenia, kaĔde takie wystñpienie naleĔy poprzedziè lewym ukoĈnikiem. MoĔna uniknñè tej koniecznoĈci, stosujñc w roli sepa- ratora znak, który nie wystöpuje w samym wyraĔeniu regularnym. Na potrzeby tej receptury uĔyto znak procenta, poniewaĔ — w przeciwieþstwie do prawego ukoĈnika — nie wystöpuje w wyraĔeniu regularnym. Gdyby nasze wyraĔenie nie zawieraäo prawego ukoĈnika, powinni- Ĉmy otoczyè je wäaĈnie tym znakiem, poniewaĔ to on jest najczöĈciej stosowanym separatorem w Perlu oraz wymaganym separatorem w jözykach JavaScript i Ruby. PHP obsäuguje zarówno äaþcuchy otoczone apostrofami, jak i äaþcuchy otoczone cudzysäo- wami. KaĔdy apostrof, cudzysäów i lewy ukoĈnik wystöpujñcy wewnñtrz wyraĔenia regular- nego wymaga zastosowania sekwencji ucieczki (poprzedzenia lewym ukoĈnikiem). W äaþcu- chach otoczonych cudzysäowami sekwencjö ucieczki naleĔy dodatkowo stosowaè dla znaku dolara. JeĈli nie planujesz wäñczania zmiennych do swoich wyraĔeþ regularnych, powinieneĈ konsekwentnie zapisywaè je w formie äaþcuchów otoczonych apostrofami. Perl W Perlu staäe wyraĔenia regularne wykorzystuje siö äñcznie z operatorem dopasowywania wzor- ców oraz operatorem podstawiania. Operator dopasowywania wzorców skäada siö z dwóch prawych ukoĈników oraz znajdujñcego siö pomiödzy nimi wyraĔenia regularnego. Prawe uko- Ĉniki w ramach tego wyraĔenia wymagajñ zastosowania sekwencji ucieczki poprzez poprze- dzenie kaĔdego z nich lewym ukoĈnikiem. ēaden inny znak nie wymaga stosowania podobnej sekwencji (moĔe z wyjñtkiem znaków $ i @, o czym napisano na koþcu tego podpunktu). Alternatywna notacja operatora dopasowywania wzorców polega na umieszczaniu wyraĔe- nia regularnego pomiödzy parñ znaków interpunkcyjnych poprzedzonñ literñ m. JeĈli w roli separatora uĔywasz dowolnego rodzaju otwierajñcych lub zamykajñcych znaków interpunk- cyjnych (nawiasów okrñgäych, kwadratowych lub klamrowych), za wyraĔeniem regularnym naleĔy umieĈciè prawy odpowiednik znaku otwierajñcego, na przykäad m{regex}. W przy- padku pozostaäych znaków interpunkcyjnych wystarczy dwukrotnie uĔyè tego samego sym- 126 _ Rozdziaĥ 3. Programowanie z wykorzystaniem wyraŜeħ regularnych bolu. W rozwiñzaniu dla tej receptury wykorzystano dwa wykrzykniki. W ten sposób uniknöli- Ĉmy koniecznoĈci stosowania sekwencji ucieczki dla prawego ukoĈnika uĔytego w ramach wyraĔenia regularnego. JeĈli zastosowano inne separatory otwierajñce i zamykajñce, symbol ucieczki (lewy ukoĈnik) jest niezbödny tylko w przypadku separatora zamykajñcego (jeĈli ten separator wystöpuje w wyraĔeniu regularnym). Operator podstawiania pod wieloma wzglödami przypomina operator dopasowywania wzor- ców. Operator podstawiania rozpoczyna siö od litery s (zamiast m), po której nastöpuje tekst docelowy operacji wyszukiwania i zastöpowania. JeĈli w roli separatorów korzystasz z nawia- sów kwadratowych lub podobnych znaków interpunkcyjnych, bödziesz potrzebowaä dwóch par: s[wyrašenie][docelowy]. Wszystkich pozostaäych znaków interpunkcyjnych naleĔy uĔyè trzykrotnie: s/wyrašenie/docelowy/. Perl traktuje operatory dopasowywania wzorców i podstawiania tak jak äaþcuchy otoczone cudzysäowami. JeĈli wiöc skonstruujemy wyraĔenie m/Mam na imiĂ $name/ i jeĈli $name repre- zentuje Jan , otrzymamy wyraĔenie regularne MamƔnaƔimiĂƔJan . TakĔe $ jest w jözyku Perl traktowane jak zmienna, stñd koniecznoĈè poprzedzenia znaku dolara (dopasowywanego dosäownie) w klasie znaków symbolem ucieczki. Sekwencji ucieczki nigdy nie naleĔy stosowaè dla znaku dolara, który ma peäniè funkcjö kotwicy (patrz receptura 2.5). Znak dolara poprzedzony symbolem ucieczki zawsze jest dopasowy- wany dosäownie. Perl dysponuje mechanizmami niezbödnymi do prawidäowego rozróĔnia- nia znaków dolara wystöpujñcych w roli kotwic oraz znaków dolara reprezentujñcych zmienne (w pierwszym przypadku znaki dolara mogñ wystöpowaè tylko na koþcu grupy lub caäego wyraĔenia regularnego bñdĒ przed znakiem nowego wiersza). Oznacza to, Ĕe jeĈli chcemy sprawdziè, czy wyrašenie w ramach konstrukcji m/^wyrašenie$/ pasuje do caäego przetwa- rzanego tekstu, nie powinniĈmy stosowaè sekwencji ucieczki dla znaku dolara. Znak @ stosowany w wyraĔeniach regularnych nie ma co prawda Ĕadnego specjalnego zna- czenia, jednak jest wykorzystywany podczas przetwarzania zmiennych. Oznacza to, Ĕe kaĔde jego wystñpienie w staäym wyraĔeniu regularnym Perla naleĔy poprzedziè symbolem ucieczki (podobnie jak w przypadku äaþcuchów otoczonych cudzysäowami). Python Funkcje moduäu re jözyka Python otrzymujñ na wejĈciu wyraĔenia regularne w formie äaþ- cuchów. Oznacza to, Ĕe dla wyraĔeþ regularnych definiowanych na potrzeby tych funkcji majñ zastosowanie rozmaite sposoby definiowania äaþcuchów Pythona. W zaleĔnoĈci od znaków wystöpujñcych w Twoim wyraĔeniu regularnym wybór wäaĈciwego sposobu definiowania äaþ- cuchów moĔe znacznie ograniczaè zakres znaków wymagajñcych stosowania sekwencji ucieczki (poprzedzania lewymi ukoĈnikami). Ogólnie najlepszym rozwiñzaniem jest stosowanie standardowych (surowych) äaþcuchów. Standardowe äaþcuchy Pythona nie wymagajñ stosowania sekwencji ucieczki dla Ĕadnych znaków. Oznacza to, Ĕe jeĈli zdecydujesz siö na tö formö definiowania wyraĔeþ regularnych, nie bödziesz musiaä podwajaè lewych ukoĈników. Konstrukcja r \d+ jest bardziej czytelna od konstrukcji \\d+ , szczególnie jeĈli caäe wyraĔenie regularne jest znacznie däuĔsze. Jedyny przypadek, w którym standardowe äaþcuchy nie sñ najlepszym rozwiñzaniem, ma miejsce wtedy, gdy wyraĔenie regularne zawiera zarówno apostrofy, jak i cudzysäowy. Standardowy äaþcuch nie moĔe wówczas byè otoczony apostrofami ani cudzysäowami, poniewaĔ nie ma 3.1. Staĥe wyraŜenia regularne w kodzie Śródĥowym _ 127 moĔliwoĈci zastosowania sekwencji ucieczki dla tych znaków wewnñtrz wyraĔenia regular- nego. W takim przypadku naleĔy otoczyè standardowy äaþcuch trzema cudzysäowami — jak w rozwiñzaniu tej receptury dla jözyka Python (dla porównania pokazano teĔ zwykäy äaþcuch). GdybyĈmy chcieli korzystaè w naszych wyraĔeniach regularnych Pythona z moĔliwoĈci, jakie daje nam standard Unicode (patrz receptura 2.7), powinniĈmy zastosowaè äaþcuchy tego standardu. Standardowy äaþcuch moĔna przeksztaäciè w äaþcuch Unicode, poprzedzajñc go przedrostkiem u. Standardowe äaþcuchy nie obsäugujñ znaków niedrukowanych poprzedzanych znakami ucieczki, na przykäad konstrukcji \n. Standardowe äaþcuchy interpretujñ tego rodzaju sekwen- cje dosäownie. Okazuje siö jednak, Ĕe wspomniana cecha standardowych äaþcuchów nie sta- nowi problemu w przypadku moduäu re, który obsäuguje tego rodzaju sekwencje w ramach skäadni wyraĔeþ regularnych oraz skäadni docelowego tekstu operacji przeszukiwania i zastö- powania. Oznacza to, Ĕe konstrukcja \n bödzie interpretowana jako znak nowego wiersza w wyraĔeniu regularnym lub tekĈcie docelowym, nawet jeĈli zdefiniujemy go w formie stan- dardowego äaþcucha. JeĈli wäñczono tryb swobodnego stosowania znaków biaäych (patrz receptura 2.18) za poĈred- nictwem re.VERBOSE, äaþcuch \n jest traktowany inaczej niĔ äaþcuch \\n i surowy äaþ- cuch r \n (patrz receptura 3.4). O ile konstrukcja \n jest interpretowana jako staäa äaþcuchowa z podziaäem wiersza, która nie pasuje do znaków biaäych, o tyle konstrukcje \\n i r \n to äaþcuchy z tokenem wyraĔenia regularnego \n , który pasuje do nowego wiersza. W trybie swobodnego stosowania znaków biaäych najlepszym rozwiñzaniem jest definiowa- nie standardowych äaþcuchów otoczonych trzema cudzysäowami (na przykäad r \n ), poniewaĔ äaþcuchy w tej formie mogñ siö skäadaè z wielu wierszy. PoniewaĔ konstrukcja \n nie jest interpretowana na poziomie äaþcucha, moĔe byè interpretowana na poziomie wyra- Ĕenia regularnego, gdzie reprezentuje token pasujñcy do podziaäu wiersza. Ruby W Ruby najlepszym sposobem tworzenia wyraĔeþ regularnych jest korzystanie ze skäadni stworzonej specjalnie z myĈlñ o staäych wyraĔeniach tego typu. Wystarczy umieĈciè wyraĔenie regularne pomiödzy dwoma prawymi ukoĈnikami. JeĈli samo wyraĔenie zawiera jakiĈ prawy ukoĈnik, naleĔy ten znak poprzedziè lewym ukoĈnikiem. JeĈli nie chcesz stosowaè sekwencji ucieczki dla prawych ukoĈników, moĔesz poprzedziè swoje wyraĔenie regularne przedrostkiem r, po czym uĔyè w roli separatora dowolnego wybranego przez siebie znaku interpunkcyjnego. Mimo Ĕe istnieje moĔliwoĈè tworzenia obiektów klasy Regexp na podstawie äaþcuchów, sto- sowanie notacji äaþcuchowej dla staäych wyraĔeþ regularnych definiowanych w kodzie Ēró- däowym nie miaäoby wiökszego sensu, poniewaĔ wymagaäoby stosowania sekwencji ucieczki dla cudzysäowów i lewych ukoĈników (co zwykle prowadzi do powstania prawdziwego gñszczu lewych ukoĈników). Pod tym wzglödem jözyk Ruby bardzo przypomina jözyk JavaScript, z tñ róĔnicñ, Ĕe w jözyku Ruby odpowiednia klasa nosi nazwö Regexp, a w JavaScripcie nazwano jñ RegExp. 128 _ Rozdziaĥ 3. Programowanie z wykorzystaniem wyraŜeħ regularnych Patrz takŜe W recepturze 2.3 wyjaĈniono sposób dziaäania klas znaków. Opisano teĔ, dlaczego w wyraĔe- niu regularnym naleĔy uĔywaè podwójnych lewych ukoĈników dla kaĔdego lewego ukoĈnika wchodzñcego w skäad klasy znaków. W recepturze 3.4 wyjaĈnimy, jak ustawiaè opcje wyraĔeþ regularnych, co w niektórych jözykach programowania jest moĔliwe w ramach staäych wyraĔeþ regularnych. 3.2. Importowanie biblioteki wyraŜeħ regularnych Problem Aby korzystaè z wyraĔeþ regularnych w tworzonych aplikacjach, naleĔy najpierw zaimporto- waè do kodu Ēródäowego bibliotekö lub przestrzeþ nazw wyraĔeþ regularnych. W pozostaäych fragmentach kodu Ēródäowego w tej ksiñĔce (poczñwszy od nastöpnej receptury) bödziemy zakäadali, Ĕe w razie koniecznoĈci zaimportowaäeĈ juĔ niezbödne biblioteki lub przestrzenie nazw. Rozwiézanie C# using System.Text.RegularExpressions; VB.NET Imports System.Text.RegularExpressions Java import java.util.regex.*; Python import re Analiza Niektóre jözyki programowania oferujñ wbudowanñ obsäugö wyraĔeþ regularnych. Korzy- stanie z wyraĔeþ regularnych w tych jözykach nie wymaga Ĕadnych dodatkowych kroków. Pozostaäe jözyki programowania udostöpniajñ obsäugö wyraĔeþ regularnych za poĈrednictwem bibliotek, które naleĔy zaimportowaè przy uĔyciu odpowiednich wyraĔeþ w kodzie Ēródäowym. Co wiöcej, niektóre jözyki w ogóle nie oferujñ obsäugi wyraĔeþ regularnych — w ich przypadku konieczne jest samodzielne skompilowanie i äñczenie moduäu implementujñcego obsäugö wyra- Ĕeþ regularnych. 3.2. Importowanie biblioteki wyraŜeħ regularnych _ 129 C# JeĈli umieĈcisz przytoczone wyraĔenie using na poczñtku swojego pliku Ēródäowego jözyka C#, bödziesz mógä bezpoĈrednio korzystaè z mechanizmów obsäugi wyraĔeþ regularnych (bez koniecznoĈci kaĔdorazowego kwalifikowania stosowanych wywoäaþ). Bödziesz mógä na przykäad uĔyè wywoäania Regex() zamiast wywoäania System.Text.RegularExpressions. ´Regex(). VB.NET JeĈli umieĈcisz przytoczone wyraĔenie Imports na poczñtku swojego pliku Ēródäowego jözyka VB.NET, bödziesz mógä bezpoĈrednio korzystaè z mechanizmów obsäugi wyraĔeþ regularnych (bez koniecznoĈci kaĔdorazowego kwalifikowania stosowanych wywoäaþ). Bödziesz mógä na przykäad uĔyè wywoäania Regex() zamiast wywoäania System.Text.RegularExpressions. ´Regex(). Java Korzystanie z wbudowanej biblioteki wyraĔeþ regularnych Javy wymaga uprzedniego zaim- portowania pakietu java.util.regex do budowanej aplikacji. JavaScript W jözyku JavaScript mechanizmy obsäugi wyraĔeþ regularnych sñ wbudowane i zawsze dostöpne. PHP Funkcje z rodziny preg sñ wbudowane i zawsze dostöpne w jözyku PHP, poczñwszy od wer- sji 4.2.0. Perl Mechanizmy obsäugujñce wyraĔenia regularne sñ wbudowanymi i zawsze dostöpnymi elemen- tami jözyka Perl. Python Warunkiem korzystania z funkcji obsäugujñcych wyraĔenia regularne w jözyku Python jest uprzednie zaimportowanie moduäu re do tworzonego skryptu. Ruby Mechanizmy obsäugujñce wyraĔenia regularne sñ wbudowanymi i zawsze dostöpnymi elemen- tami jözyka Ruby. 130 _ Rozdziaĥ 3. Programowanie z wykorzystaniem wyraŜeħ regularnych 3.3. Tworzenie obiektów wyraŜeħ regularnych Problem Chcesz skonkretyzowaè obiekt wyraĔenia regularnego lub tak skompilowaè swoje wyraĔenie, aby umoĔliwiè efektywne uĔywanie tego wyraĔenia w caäej swojej aplikacji. Rozwiézanie C# JeĈli wiesz, Ĕe Twoje wyraĔenie regularne jest prawidäowe: Regex regexObj = new Regex( wzorzec wyrašenia regularnego ); JeĈli wyraĔenie regularne zostaäo wpisane przez uĔytkownika koþcowego (gdzie UserInput jest zmiennñ äaþcuchowñ): try { Regex regexObj = new Regex(UserInput); } catch (ArgumentException ex) { // Bäñd skäadniowy we wpisanym wyraĔeniu regularnym. } VB.NET JeĈli wiesz, Ĕe Twoje wyraĔenie regularne jest prawidäowe: Dim RegexObj As New Regex( wzorzec wyrašenia regularnego ) JeĈli wyraĔenie regularne zostaäo wpisane przez uĔytkownika koþcowego (gdzie UserInput jest zmiennñ äaþcuchowñ): Try Dim RegexObj As New Regex(UserInput) Catch ex As ArgumentException Bäñd skäadniowy we wpisanym wyraĔeniu regularnym. End Try Java JeĈli wiesz, Ĕe Twoje wyraĔenie regularne jest prawidäowe: Pattern regex = Pattern.compile( wzorzec wyrašenia regularnego ); JeĈli wyraĔenie regularne zostaäo wpisane przez uĔytkownika koþcowego (gdzie userInput jest zmiennñ äaþcuchowñ): try { Pattern regex = Pattern.compile(userInput); } catch (PatternSyntaxException ex) { // Bäñd skäadniowy we wpisanym wyraĔeniu regularnym. } Aby dopasowaè to wyraĔenie regularne dla äaþcucha, naleĔy utworzyè obiekt klasy Matcher: Matcher regexMatcher = regex.matcher(subjectString); 3.3. Tworzenie obiektów wyraŜeħ regularnych _ 131 Dopasowanie tego wyraĔenia regularnego do innego äaþcucha wymaga albo utworzenia nowego obiektu klasy Matcher (jak w powyĔszym wyraĔeniu), albo ponownego uĔycia obiektu juĔ istniejñcego: regexMatcher.reset(anotherSubjectString); JavaScript Staäe wyraĔenie regularne w Twoim kodzie moĔe mieè nastöpujñcñ postaè: var myregexp = /wzorzec wyrašenia regularnego/; WyraĔenie regularne wpisane przez uĔytkownika ma postaè äaþcucha reprezentowanego przez zmiennñ userinput: var myregexp = new RegExp(userinput); Perl $myregex = qr/wzorzec wyrašenia regularnego/ W tym przypadku wyraĔenie regularne wpisane przez uĔytkownika jest reprezentowane przez zmiennñ $userinput: $myregex = qr/$userinput/ Python reobj = re.compile( wzorzec wyrašenia regularnego ) WyraĔenie regularne wpisane przez uĔytkownika ma postaè äaþcucha reprezentowanego przez zmiennñ userinput: reobj = re.compile(userinput) Ruby Staäe wyraĔenie regularne w Twoim kodzie moĔe mieè nastöpujñcñ postaè: myregexp = /wzorzec wyrašenia regularnego/; WyraĔenie regularne wpisane przez uĔytkownika ma postaè äaþcucha reprezentowanego przez zmiennñ userinput: myregexp = Regexp.new(userinput); Analiza Zanim moduä wyraĔeþ regularnych moĔe dopasowaè jakieĈ wyraĔenie do äaþcucha, naleĔy to wyraĔenie skompilowaè. Kompilacja wyraĔenia regularnego ma miejsce dopiero w czasie dzia- äania naszej aplikacji. Konstruktor wyraĔenia regularnego lub odpowiednia funkcja kompi- latora poddaje äaþcuch zawierajñcy nasze wyraĔenie analizie skäadniowej i konwertuje go na strukturö drzewa lub maszynö stanów. Funkcja odpowiedzialna za wäaĈciwe dopasowywanie wzorców przeszukuje to drzewo lub maszynö stanów w trakcie przetwarzania tego äaþcucha. Jözyki programowania, które obsäugujñ staäe wyraĔenia regularne, kompilujñ te wyraĔenia w momencie osiñgniöcia operatora wyraĔenia regularnego. 132 _ Rozdziaĥ 3. Programowanie z wykorzystaniem wyraŜeħ regularnych .NET W jözykach C# i VB.NET klasa System.Text.RegularExpressions.Regex frameworku .NET reprezentuje jedno skompilowane wyraĔenie regularne. Najprostsza wersja konstruktora tej klasy otrzymuje na wejĈciu tylko jeden parametr — äaþcuch zawierajñcy nasze wyraĔenie regularne. W razie wystöpowania jakiegoĈ bäödu skäadniowego w przekazanym wyraĔeniu regularnym konstruktor Regex() generuje wyjñtek ArgumentException. Komunikat doäñczony do tego wyjñtku precyzyjnie okreĈla rodzaj napotkanego bäödu. JeĈli wyraĔenie regularne zostaäo wpi- sane przez uĔytkownika naszej aplikacji, niezwykle waĔne jest przechwycenie ewentualnego wyjñtku. W razie jego wystñpienia naleĔy wyĈwietliè stosowny komunikat i poprosiè uĔyt- kownika o poprawienie wpisanego wyraĔenia. JeĈli wyraĔenie regularne trwale zakodowano w formie staäej äaþcuchowej, moĔemy zrezygnowaè z przechwytywania wyjñtku (warto jed- nak uĔyè narzödzia badajñcego pokrycie kodu, aby upewniè siö, Ĕe odpowiedni wiersz nie powoduje wyjñtków). Trudno sobie wyobraziè, by wskutek zmian stanu lub trybu to samo staäe wyraĔenie regularne w jednej sytuacji byäo kompilowane prawidäowo, a w innej odrzu- cane przez kompilator. Warto przy tym pamiötaè, Ĕe w razie bäödu skäadniowego w staäym wyraĔeniu regularnym odpowiedni wyjñtek bödzie generowany dopiero w czasie wykonywa- nia aplikacji (nie na etapie jej kompilacji). Obiekt klasy Regex naleĔy skonstruowaè w sytuacji, gdy dane wyraĔenie regularne ma byè wykorzystywane w pötli lub wielokrotnie w róĔnych czöĈciach kodu aplikacji. Konstruowa- nie obiektu wyraĔenia regularnego nie wiñĔe siö z Ĕadnymi dodatkowymi kosztami. Okazuje siö bowiem, Ĕe takĔe statyczne skäadowe klasy Regex, które otrzymujñ wyraĔenia regularne za poĈrednictwem parametrów äaþcuchowych, wewnötrznie konstruujñ obiekty tej klasy (na wäasne potrzeby). Oznacza to, Ĕe równie dobrze moĔna to zrobiè samodzielnie w kodzie Ēró- däowym i zyskaè moĔliwoĈè swobodnego dysponowania odwoäaniem do tego obiektu. JeĈli planujemy uĔyè danego wyraĔenia regularnego zaledwie raz lub kilka razy, moĔemy uĔyè statycznych skäadowych klasy Regex i — tym samym — oszczödziè sobie koniecznoĈci wpi- sywania dodatkowego wiersza kodu. Statyczne skäadowe tej klasy co prawda nie zwracajñ wewnötrznie konstruowanego obiektu wyraĔenia regularnego, ale przechowujñ w wewnötrznej pamiöci podröcznej piötnaĈcie ostatnio uĔytych wyraĔeþ regularnych. Rozmiar tej pamiöci moĔna zmieniè za poĈrednictwem wäaĈciwoĈci Regex.CacheSize. Przeszukiwanie wewnötrznej pamiöci podröcznej klasy Regex polega na odnajdywaniu äaþcucha z odpowiednim wyraĔe- niem regularnym. Nie naleĔy jednak przeciñĔaè tej pamiöci — jeĈli czösto odwoäujesz siö do wielu róĔnych obiektów wyraĔeþ regularnych, stwórz wäasnñ pamiöè podröcznñ, którñ bödziesz mógä przeszukiwaè nieporównanie szybciej niĔ w modelu odnajdywania äaþcuchów. Java W Javie klasa Pattern reprezentuje pojedyncze, skompilowane wyraĔenie regularne. Obiekty tej klasy moĔna tworzyè za poĈrednictwem fabryki (wytwórni) klas w formie metody Pattern. ´compile(), która otrzymuje na wejĈciu tylko jeden parametr — nasze wyraĔenie regularne. W razie wystöpowania bäödu skäadniowego w przekazanym wyraĔeniu regularnym fabryka Pattern.compile() generuje wyjñtek PatternSyntaxException. Komunikat doäñczony do tego wyjñtku precyzyjnie okreĈla rodzaj napotkanego bäödu. JeĈli wyraĔenie regularne zostaäo wpisane przez uĔytkownika naszej aplikacji, niezwykle waĔne jest przechwycenie ewentualnego wyjñtku. W razie jego wystñpienia naleĔy wyĈwietliè stosowny komunikat i poprosiè uĔyt- kownika o poprawienie wpisanego wyraĔenia. JeĈli wyraĔenie regularne trwale zakodowano 3.3. Tworzenie obiektów wyraŜeħ regularnych _ 133 w formie staäej äaþcuchowej, moĔemy zrezygnowaè z przechwytywania wyjñtku (warto jed- nak uĔyè narzödzia badajñcego pokrycie kodu, aby upewniè siö, Ĕe odpowiedni wiersz nie powoduje wyjñtków). Trudno sobie wyobraziè, by wskutek zmian stanu lub trybu to samo staäe wyraĔenie regularne w jednej sytuacji byäo kompilowane prawidäowo, a w innej odrzu- cane przez kompilator. Warto przy tym pamiötaè, Ĕe w razie bäödu skäadniowego w staäym wyraĔeniu regularnym odpowiedni wyjñtek bödzie generowany dopiero w czasie wykonywa- nia aplikacji (nie na etapie jej kompilacji). JeĈli nie planujesz uĔyè swojego wyraĔenia regularnego zaledwie raz, powinieneĈ skonstruowaè obiekt klasy Pattern, zamiast korzystaè ze statycznych skäadowych klasy String. Skonstru- owanie tego obiektu wymaga co prawda kilku dodatkowych wierszy kodu, jednak kod w tej formie bödzie wykonywany szybciej. Nie doĈè, Ĕe wywoäania statyczne kaĔdorazowo kom- pilujñ Twoje wyraĔenie regularne, to jeszcze Java oferuje wywoäania statyczne dla zaledwie kilku najprostszych zadaþ zwiñzanych z przetwarzaniem wyraĔeþ regularnych. Obiekt klasy Pattern ogranicza siö do przechowywania skompilowanego wyraĔenia regu- larnego — nie wykonuje wäaĈciwych zadaþ zwiñzanych z dopasowywaniem tego wyraĔenia. Za dopasowywanie wyraĔeþ regularnych odpowiada klasa Matcher. Utworzenie obiektu tej klasy wymaga wywoäania metody matcher() dla skompilowanego wyraĔenia regularnego. Za poĈrednictwem jedynego argumentu metody matcher() naleĔy przekazaè äaþcuch, do którego ma byè dopasowane dane wyraĔenie. Metodö matcher() moĔna wywoäaè dowolnñ liczbö razy dla tego samego wyraĔenia regular- nego i wielu äaþcuchów do przetworzenia. Co wiöcej, istnieje moĔliwoĈè jednoczesnego korzy- stania z wielu metod dopasowujñcych to samo wyraĔenie regularne, ale pod warunkiem reali- zacji wszystkich tych zadaþ w ramach pojedynczego wñtku. Klasy Pattern i Matcher nie gwarantujñ bezpieczeþstwa przetwarzania wielowñtkowego. JeĈli wiöc chcemy korzystaè z tego samego wyraĔenia w wielu wñtkach, powinniĈmy w kaĔdym z tych wñtków uĔyè osobnego wywoäania metody Pattern.compile(). Kiedy juĔ zakoþczymy stosowanie naszego wyraĔenia regularnego dla jednego äaþcucha i posta- nowimy zastosowaè to samo wyraĔenie dla innego äaþcucha, bödziemy mogli ponownie uĔyè istniejñcego obiektu klasy Matcher, wywoäujñc metodö skäadowñ reset(). Za poĈrednictwem jedynego argumentu tej metody naleĔy przekazaè kolejny äaþcuch do przetworzenia. Takie roz- wiñzanie jest bardziej efektywne niĔ kaĔdorazowe tworzenie nowego obiektu klasy Matcher. Metoda reset() zwraca bowiem ten sam obiekt klasy Matcher, dla którego zostaäa wywoäana. Oznacza to, Ĕe moĔna bez trudu przywróciè pierwotny stan i ponownie uĔyè obiektu dopaso- wujñcego w jednym wierszu kodu, na przykäad stosujñc konstrukcjö regexMatcher.reset ´(nextString).find(). JavaScript Notacja dla staäych wyraĔeþ regularnych, którñ pokazano w recepturze 3.2, tworzy nowy obiekt wyraĔenia regularnego. Jedynym warunkiem ponownego uĔycia tego samego obiektu jest przy- pisanie go jakiejĈ zmiennej. JeĈli dysponujemy wyraĔeniem regularnym reprezentowanym przez zmiennñ äaþcuchowñ (na przykäad wyraĔeniem wpisanym przez uĔytkownika aplikacji), moĔemy uĔyè konstruktora RegExp() do jego skompilowania. Warto pamiötaè, Ĕe wyraĔenie regularne przechowywane 134 _ Rozdziaĥ 3. Programowanie z wykorzystaniem wyraŜeħ regularnych w formie äaþcucha nie jest otoczone prawymi ukoĈnikami. Prawe ukoĈniki sñ czöĈciñ notacji JavaScriptu stosowanej dla staäych obiektów klasy RegExp i jako takie nie wchodzñ w skäad samego wyraĔenia regularnego. PoniewaĔ przypisywanie staäych wyraĔeþ regularnych zmiennym jest dziecinnie proste, wiökszoĈè prezentowanych w tym rozdziale rozwiñzaþ dla JavaScriptu nie bödzie zawieraäa tego wiersza kodu — bödziemy raczej bezpoĈrednio korzystali ze staäego wyraĔenia regularnego. JeĈli w swoim kodzie korzystasz z tego samego wyra- Ĕenia regularnego wiöcej niĔ raz, powinieneĈ przypisaè to wyraĔenie jakiejĈ zmiennej i w kolejnych odwoäaniach uĔywaè wäaĈnie tej zmiennej (zamiast kaĔdorazowo kopio- waè i wklejaè to samo staäe wyraĔenie regularne). Takie rozwiñzanie nie tylko poprawia wydajnoĈè tworzonych aplikacji, ale teĔ zwiöksza czytelnoĈè kodu. PHP Jözyk PHP nie oferuje mechanizmu przechowywania skompilowanych wyraĔeþ regularnych w zmiennych. JeĈli chcesz wykonaè jakñĈ operacjö na wyraĔeniu regularnym, musisz to wyra- Ĕenie przekazaè w formie äaþcucha na wejĈciu odpowiedniej funkcji preg. Funkcje z rodziny preg przechowujñ w wewnötrznej pamiöc
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

Wyrażenia regularne. Receptury
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ą: