Regulární výrazy v shellu
'''Regulární výrazy''', nebo také '''regexpy''' (z anglického ''regular expression'') slouží pro porovnávání textů s nějakou maskou.
S nejjednodušším použitím tohoto jsme se již setkali: v metaznacích shellu slouží znaky * a ? k zobecnění jména souborů o nespecifikované množství znaků (*), nebo o jeden (?). Regulární výrazy podle POSIX specifikace jsou ovšem mnohem silnější...
Mnoho řádkových programů dokáže s regulárními výrazy přímo pracovat: ''vi'', ''sed'', ''ed'', ''grep'', ''more'', ''expr'', ''awk'' a další.
Poznámka:
Regulárních výrazů je více druhů. My budeme probírat základní výrazy podle POSIX specifikace - které jsou jistojistě kompatibilní se všemi našimi příkazy. V rozšířených(extended) POSIX výrazech přibývají některé další metaznaky (?,+) a nemusí se již escapovat závorky. Pokud chcete používat extended výrazy, použijte parametr -E.
Existují ale i další větve regulárních výrazů, například Perl-compatible. Principy jsou tam podobné, syntaxe se samozřejmě často liší.
Úlohy
Na co jsou regulární výrazy vhodné?
- '''Match''' - dá se v textu nalézt řetězec vyhovující regulárnímu výrazu?
- '''Replace''' - vem text, a změň v něm oblast vyhovující regulárnímu výrazu na nějaký jiný řetězec (případně se zpětnými referencemi).
Metaznaky
'''KOTVY:'''
- '''^''' - začátek (většinou řádku)
- '''$''' - konec
Příklady:
- ^A - A na začátku
- A$ - A na konci
'''.''' - tečka : jakýkoliv znak
(pozor, tečka je tedy metaznak a pokud jej chcete použít doslovně, musíte ji escapovat!)
Příklady:
- a.c - matchuje řetězce "abc", "aDc", "aPc", "a$c", "a c" a tak podobně
- ^..$ - řádek přesně se dvěma znaky
'''[]''' - '''Seznam / rozsah znaků''':
Příklady:
- [abc] - jakékoliv z písmenek abc.
- [a-zA-Z] - malé či velké písmenko
- [0-9] - číslice
- [02468] - sudé číslice
- [Aa][Hh][Oo][Jj] - 'ahoj', 'Ahoj', 'ahOJ','AhoJ', atd.
'''^''' (na začátku seznamu znaků): '''Negace''':
Příklady:
- [^a-zA-Z] - jakýkoliv znak krom písmenka
- [^:] - cokoliv krom znaku : ... použitelné při parsování /etc/passwd
'''''' - opakování - určité
Příklady:
- b - přesně tři znaky b
- a - pět až deset znaků a
- [0-9]{1-3}.[0-9]{1-3}.[0-9]{1-3}.[0-9] - jednoduchá verze regexpu pro IPv4 adresu (matchuje ale i nesmyslné adresy jako 999.999.999.999)
- Praha [0-9] matchuje 'Praha 3', 'Praha 6', 'Praha 14', 'Praha 613'... ale ne osamělé 'Praha'
'''*''' - opakování - neurčité
Hvězdička dělá to samé, jako hypotetické . Prostě matchuje libovolný (pozor, i nulový!) výskyt.
Příklady:
- ab*c - matchuje 'ac', 'abbc', 'abc', 'abbbbbbbbbbbc'
SLOVA:
'''< >''' - slova
Příklady:
- <test> - matchuje "tohle je test", "toto test je", ale ne "testovaci stranka"
- "<[tT]est>" - jako nahoře, ale odhalí i Test (s velkým T).
'''Závorkování, reference a pamatování'''
Kulaté (escapované) závorky se nám hodí na dvě věci:
- jako v matematice na uzávorkování výrazů. (ab)* znamená libovolné opakování řetězce 'ab'. Do závorek můžeme zkrátka nacpat jakýkoliv regexp - a poté naň použít operátor pro opakování.
- Zpětné reference: výraz v závorkách si můžeme poté pomocí čísla za zpětným lomítkem vybavit. Číslo odpovídá pořadí závorky.
Příklady na zpětné reference:
- ([a-zA-Z])1 - matchuje dvojhlásky (''aa'',''ww'', atd. Nematchuje ale 'Aaron')
- ([a-z])([a-z])[a-z]21 - matchuje pětipísmený palindrom (slovo které čtené odzadu je stejné jako odpředu)
Zpětné reference se dají použít v operaci zaměňování i v řetězci, jímž původní oblast nahrazujeme. Dají se tak parsovat informace, které chceme:
Příklady:
- sed 's/^.*Praha ([0-9]).*$/ - nám z textu vytahá pouze čísla Pražských obvodů. (na řádcích, kde se vyskytuje slovo 'Praha ')
To už se ale lehce dostáváme k sedu, o kterém si povíme příště.