Wyrażenia regularne Wojciech Tabiś Łukasz Jankowski
Wyrażenia regularne: ang. Regular expressions (regexp) Wyrażenia regularne są narzędziem służącym do dopasowywania wzorców.. Wykorzystywane są tam, gdzie potrzebne jest narzędzie do wyszukiwania tekstu spełniającego pewne kryteria. 2
Wyrażenia regularne: składnia Znaki zwyczajne a, A, b, B, z, Z, 0, 1, 9,,! Znaki specjalne (metaznaki) Rozróżnia się dwa zbiory metaznaków: metaznaki rozpoznawane w dowolnym miejscu wzorca poza nawiasami kwadratowymi ^, $, *, +,?,., (, ), [, ], {, }, \ oraz metaznaki rozpoznawane wewnątrz nawiasów kwadratowych. \, ^, -, ] Część wzorca ujęta w nawiasy kwadratowe jest zwana "klasą znaków". 3
Elementy wyrażeń regularnych: dopasowywanie tekstu Każdy znak oprócz znaków specjalnych określa sam siebie, np.: "a" określa łańcuch złożony ze znaku a Kolejne symbole oznaczają, że w łańcuchu muszą wystąpić dokładnie te symbole w dokładnie takiej samej kolejności, np.: "ab3" oznacza łańcuch składający się z liter a, b i cyfry 3 "wyrażenie regularne" oznacza wyrażenie regularne 4
Elementy wyrażeń regularnych: znaki specjalne Kropka "." oznacza dowolny znak z wyjątkiem znaku nowego wiersza np.: "r.k" - pasuje do słów rak, rok, ryk itd... ".a." - mak, rak, lat itd... ".o.a" - lola, wola, cola, rola, kolano!! itd Pałka " " to operator OR np.: Jeśli napiszemy "a b c" oznacza to, że w danym wyrażeniu może wystąpić a, b lub c Jeśli napiszemy "Ala Ola" oznacza to, że w danym wyrażeniu wystąpić może Ala lub Ola 5
Elementy wyrażeń regularnych: znaki specjalne - grupowanie Podwzorzec może być zamknięty w niepodzielnej grupie za pomocą nawiasów "( )".. W ten sposób można użyć gałęzi nie tylko dla całego wzorca, ale też dla jego fragmentów. np.: Wzorzec "Fizy(k cy)" oznacza Fizyk i Fizycy Zestaw znaków między nawiasami kwadratowymi oznacza dowolny znak objęty nawiasami kwadratowymi, np.: "[abc]" oznacza a, b lub c.. Można używać także przedziałów: "[a-c]" "pi[wk]o" oznacza wzorce piwo i piko 6
Elementy wyrażeń regularnych: znaki specjalne - zakotwiczenia Daszek "^" oznacza początek wiersza, dolar "$" oznacza koniec wiersza. np.: "^.o.a$" Wyrażenie odpowiada ciągowi dokładnie czterech znaków typu cola, soja, pola itd... występujących samotnie w wierszu "^Do.*zuk$" - Do biedronki przyszedl zuk Daszek "^" na początku zestawu oznacza wszystkie znaki oprócz tych z zestawu. Większość znaków specjalnych w tym miejscu traci swoje znaczenie np.: "[^piwo]" wyszukuje łańcuchy w których nie występuje piwo np.: "pi[^wk]o" wyklucza wyrażenia piwo piko ale nie wyklucza ciągu pilot 7
Elementy wyrażeń regularnych: znaki specjalne powtórzenia Znak zapytania "?" po symbolu oznacza najwyżej jedno (być może zero) wystąpienie poprzedzającego wyrażenia Gwiazdka "*" po symbolu, (nawiasie, pojedynczym znaku) nazywana jest dopełnieniem Kleene'a i oznacza zero lub więcej wystąpień poprzedzającego wyrażenia Plus "+" po symbolu oznacza co najmniej jedno wystąpienie poprzedzającego go wyrażenia 8
Elementy wyrażeń regularnych: znaki specjalne porównanie?, *, + "ko?t" - pasuje do wzorców kt, kot "ko*t" - pasuje do wzorców kt, kot, koot, kooot, koooot,... "ko+t" - pasuje do wzorców kot, koot, kooot, koooot,... 9
Elementy wyrażeń regularnych: znaki specjalne odwrotny ukośnik Znaki specjalne poprzedzone odwrotnym ukośnikiem "\" powodują, że poprzedzanym znakom nie są nadawane żadne dodatkowe znaczenia - oznaczają same siebie, np.: "\." oznacza znak kropki (nie dowolny znak) "\\" oznacza odwrotny ukośnik ".*\.roz" wyrażenie typu dowolna_nazwa_pliku.roz 10
Elementy wyrażeń regularnych: znaki specjalne odwrotny ukośnik Za pomocą odwrotnego ukośnika są oznaczane znaki niedrukowalne w wyrażeniach, dzięki czemu można je rozróżnić w zapisie. np.: "\e" oznacza znak escape "\f" oznacza nową stronę "\n" oznacza nowy wiersz "\r" oznacza powrót karetki "\t" oznacza tabulację "\cx" znak "control-x", x jest dowolnym znakiem "\xhh" Znak o kodzie szesnastkowym "\a" Sygnał dźwiękowy, czyli znak BEL 11
Wyrażenia regularne: predefiniowane klasy znaków - rozszerzenia perla Odwrotny ukośnik jest używany do oznaczania określonych rodzajów znaków: "\d" Dowolna cyfra dziesiętna "\D" Dowolny znak nie będący cyfrą dziesiętną "\s" Dowolny znak drukowalnego odstępu (spacja) "\S" Dowolny znak nie będący drukowalną spacją "\w" Dowolny znak należący do "słowa "pi\w" oznacza wyrażenia zaczynające się od pi "\wka" oznacza wyrażenia kończące się na ka "\W" Dowolny znak spoza "słowa" 12
"/<" oznacza początek słowa np.: Wyrażenia regularne: granice wyrazów "/<fi" wyrazy zaczynające się od fi (fizyk, fizyka, fiołek ) "/>" oznacza koniec słowa np.: "ot/>" wyrazy kończące się na ot (kot, lot, plot ) np.: "\<słowo/>" oznacza że słowo jest wyrazem samodzielnym "\<słow(o a)/>" to słowo i słowa 13
Wyrażenia regularne: predefiniowane klasy znaków Rozszerzony zapis przedziałów, wprowadzenie klas znaków np.: "[[:digit:]]" oznacza dowolną cyfrę "[[:alpha:]]" literę "[[:alnum:]]" literę lub cyfrę "[[:xdigit:]]" liczby w systemie szesnastkowym "[[:lower:]]" małe litery "[[:upper:]]" duże litery "[[:punct:]]" znaki interpunkcji 14
Wyrażenia regularne: predefiniowane klasy znaków Kilka prostych przykładów: "[[:digit:]]{2}" oznacza dwucyfrowy ciąg "\<[[:digit:]]{2,4}>\" oznacza liczby dwu, trzy i czterocyfrowe "\<[[:alnum:]]{0,8}\.[[:alnum:]]{3}\>" DOSowskie nazwy plików 15
Wyrażenia regularne: liczba powtórzeń Możliwość precyzyjnego określenia liczby wystąpień danego wyrażenia Wyrażenie {N} oznacza dokładnie N wystąpień Wyrażenie {N,} co najmniej N wystąpień wyrażenia {0,}=* {1,}=+ Wyrażenie {,M} co najwyżej M wystąpień wyrażenia Wyrażenie {N,M} od N do M wystąpień wyrażenia {0,1}=? 16
Wyrażenia regularne: programy W systemie UNIX posługując się wieloma poleceniami można stosować wyrażenia regularne, np. grep, vi, sed, awk, ls, cat, head, less, more, tail, find, cp, ps, rm, gzip, tar. We wszystkich przypadkach chodzi o wyszukanie w pliku lub jego nazwie pewnego ciągu znaków, który można opisać właśnie za pomocą wyrażenia regularnego. Oprócz zwykłych fragmentów tekstu, można posłużyć się znakami specjalnymi. 17
grep (Global Regular Expression Print) Składnia: Wyrażenia regularne: programy - grep grep [opcje] wzorzec [plik] grep [opcje] [-e wzorzec -f plik] [plik] Program grep jest tzw. filtrem. Generalnie filtr jest programem, który czyta dane ze standardowego wejścia, przetwarza je i wypisuje wynik na standardowym wyjściu. grep, egrep, fgrep - przeszukuje wskazane pliki wejściowe (lub standardowe wejście) szukając linii zawierających ciąg pasującego do podanego wzorca egrep jest tym samym, co grep E, fgrep jest tym samym, co grep F 18
Najważniejsze opcje: Wyrażenia regularne: programy - grep -A num - wypisuje po pasujących liniach num linii następującego kontekstu -B num - przed pasującymi liniami num linii poprzedzającego kontekstu -C [num] - wypisuje num linii (domyślnie 2) kontekstu w wyjściu -E - interpretuje wzorzec jako rozszerzone wyrażenie regularne -e wzorzec - używa wzorca jako wzorca, użyteczne do ochronienia wzorów zaczynających się od `-' -F - interpretuje wzorzec jako listę łańcuchów o stałej długości, oddzielonych znakami nowej linii, które należy dopasować każdy z osobna -f plik - pobiera wzorce z pliku, po jednym z każdej linii -H - dla każdego dopasowania wypisuje nazwę pliku 19
Najważniejsze opcje c.d. : Wyrażenia regularne: programy - grep -h - wyłącza poprzedzanie wyników nazwami plików podczas przeszukiwania wielu plików --help - wypisuje krótki tekst pomocy -i - ignoruje rozróżnienia w wielkości liter we wzorcu oraz w plikach wejściowych -n - poprzedza każdą linię wyjścia numerem linii z odpowiedniego pliku wejściowego -q - wyłącza normalne wyjście. Przeszukiwanie zakończy się na pierwszej pasującej linii. Zobacz też opcję -s -r - czyta wszystkie pliki pod każdym katalogiem, rekurencyjnie -s - wyłącza komunikaty błędów o plikach nieistniejących lub nie do odczytania 20
Wyrażenia regularne: programy - sort sort - sortuje, zlepia lub porównuje wszystkie linie z podanych plików, lub standardowego wejścia jeśli nie podano żadnych. Program sort umożliwia uporządkowanie linii pliku tekstowego względem dowolnej kolumny (przez kolejną kolumnę rozumie się tu kolejne wyrazy w linii) w kolejności alfabetycznej lub liczbowej, rosnąco lub malejąco. Kryteria sortowania zależą od podanych w wywołaniu programu opcji. 21
Najważniejsze opcje : Wyrażenia regularne: programy - sort +2 - pominięcie podczas sortowania pierwszych 2 kolumn w każdej linii -3 - ograniczenie sortowania do 3 kolumny +3.1 - pominięcie 3 kolumn i 1 znaku kolumny następnej -3.3 - pominięcie wszystkiego co znajduje się za 3 kolumnami i 3 znakami. -b (blank) - ignoruje początkowe znaki puste podczas szukania kluczy sortowania -f - duże i małe litery traktowane są identycznie -g - sortuje numerycznie, posługując się standardową funkcją C strtod, przekształcając przedrostek każdej linii na liczbę zmiennoprzecinkową podwójnej precyzji. Umożliwia to podawanie liczb zmienno przecinkowych w notacji naukowej, jak '1.0e-34' czy '10e100'. -n (numeric) - sortowanie numeryczne, nie jest rozpoznawany ani początkowy znak '+', ani notacja wykładnicza. Do porównywania numerycznego takich łańcuchów 22 należy użyć opcji -g.
Najważniejsze opcje c.d. : Wyrażenia regularne: programy - sort -o (output) - zapisanie wyniku posortowania w pliku o podanej nazwie -r (reverse) - odwraca rezultat porównania -u (unique) - usunięcie duplikatów linii Przykłady działania sort: $ sort plik a. 284 Sierotka Marysia b. 96 Dracula hrabia c. 7763 John Rambo $ sort -n +1 plik b. 96 Dracula hrabia a. 284 Sierotka Marysia c. 7763 John Rambo 23
Wyrażenia regularne: programy - uniq uniq wypisuje unikatowe linie sortowanego pliku, odrzucając wszystkie poza jedną linią szeregu pasujących do siebie. Może opcjonalnie pokazywać tylko linie które pojawiają się tylko raz, bądź linie które pojawiają się więcej niż raz. uniq wymaga posortowanego wejścia, ponieważ porównuje tylko linie sąsiadujące ze sobą. 24
Kilka przykładów użycia: Wyrażenia regularne: praktyczne zastosowania jak wyszukać linie rozpoczynających się od cyfry? grep '^[0-9]' * jak wyszukać nazwy plików i numery linii kończących się na k lub K? grep -n '[kk]$' * jak wyświetlić nazwy plików nie zawierających wyrazów `plik'? grep -lwv 'plik' * co jeśli wzorzec zaczyna się od `-'? grep -e '--cut here--' * - szuka wszystkich linii pasujących do `--cut here--'. Bez `-e', grep próbowałby analizować `--cut here--' jako listę opcji. 25
Kilka przykładów użycia c.d. : Wyrażenia regularne: praktyczne zastosowania jak wypisać linie sąsiadujące z pasującymi? grep -C 2 'hello' * - wypisuje dwie linie kontekstu wokół każdej z dopasowanych linii. jak wykorzystać wyrażenia regularne z wyjściem z ps? ps -ef grep '[c]ron' - jeśli wzorzec zostałby zapisany bez nawiasów kwadratowych, dopasowałby nie tylko linię wyjściową z ps dotyczącą cron, ale i linię wyjściową ps dla samego grep jak wyfiltrować z listingu aktualnego katalogu tylko te nazwy, które maja rozszerzenie `.txt'? ls l grep '.*\.txt' 26
Kilka przykładów użycia c.d. : Wyrażenia regularne: praktyczne zastosowania jak znaleźć informację o swoim koncie w pliku `/etc/passwd'? cat /etc/passwd grep 'twoja_nazwa_konta' ile użytkowników serwera ma na imię tak jak Ty? cat /etc/passwd grep 'twoje_imię' wc jak znaleźć wszystkie pliki o rozszerzeniu `.txt' w Twoim katalogu domowym o rozmiarze ponad 2 kb? find ~ -type f -name '*.txt' -size +2k 27
Kilka przykładów użycia c.d. : Wyrażenia regularne: praktyczne zastosowania jak utworzyć spis tabel dokumentu o nazwie `opis.html' zapisanego w języku HTML? Do tworzenia tabel służy element table. Będziemy poszukiwać znacznika otwierającego ten element, a ściślej - jego początkowej frazy `<table'. Nawiasu `>' zamykającego znacznik nie ujmiemy w poszukiwanej frazie, by wyniki wyszukiwania zawierały także znaczniki z parametrami, takie jak `<table align="center">', `<table border="1">' czy też `<table class="tabelka">'. Do wykonania zadania zastosujemy program grep. Z uwagi na to, że nazwy elementów HTML mogą być pisane małymi lub wielkimi literami, użyjemy opcji -i (skrót od ignore letter case). Potrzebujemy też numerów wierszy pliku, by móc łatwo zidentyfikować wyszukane tabele (opcja -n, ang. line numbers): grep -i -n '<table' opis.html > spis-tabel 28
Kilka przykładów użycia c.d. : Wyrażenia regularne: praktyczne zastosowania jak odnaleźć w pliku adresy e-mail? egrep "([-[:alnum:]\.]+@ [-:alnum:]]+\.[[:alnum:]\.]+)" plik jak odnaleźć w pliku linki www? egrep "((http(s?):\/\/) (www\.))([[:alnum:]]+\. [[:alnum:]]+)" plik 29
Wyrażenia regularne: Zadania Dany jest plik: ~lukaszj/unix/dane 1. Znajdują się w nim m.in. kody pocztowe wraz z nazwami miejscowości (w formacie 00-000 Poczta). Korzystając z wiadomości uzyskanych na zajęciach proszę podać liczbę różnych kodów pocztowych zawartych w tym pliku. 2. W tymże pliku znajdują się daty w różnych formatach (dd.mm.rr, dd.mm.rrrr, dd-mm-rr, dd-mm-rrrr, ) Proszę podać te daty. 3. W tym samym pliku znajdują się 4 liczby zmiennopozycyjne. Proszę je podać (kropka jako separator części całkowitej i dziesiętnej). 30
Wyrażenia regularne: Zadania c.d. Napisz wyrażenie regularne wypisujące z pliku wszystkie linie, które: zawierają słowa hop i hoop, ale nie hooop kończą się literami x lub y zawierają trzyliterowe ciągi znaków, zaczynające się od litery a lub b zawierają ciągi znaków zaczynające się literą w lub W, następnie dwa dowolne znaki, potem znak dolara ($) i dalej dowolne znaki aż do końca linii zawierają dowolny ciąg znaków, rozpoczynający się samogłoską zawierają sześcioliterowy ciąg znaków, z których pierwszy, trzeci i piąty znak może być dowolny, drugi i czwarty musi być wielką literą, szósty musi być literą e rozpoczynają się znakami U lub u i kończące się kropką, z dowolną ilością dowolnych znaków między nimi zawierają słowa Jan Kowalski lub Stanisław Kowalski nie są puste 31