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é?

Metaznaky

'''KOTVY:'''

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ě.