☰ menu
Pavel Satrapa

Regulární výrazy - část 1
Znaky

Unix bez regulárních výrazů je jako sex bez partnera/partnerky. Dá se to používat, ale člověk o cosi zásadního přichází. Znalost regulárních výrazů vám dá do rukou mimořádně silný nástroj pro práci s textem. Jejich prostřednictvím můžete:

Zkrátka regulární výraz je univerzální pomocník při práci s textem. Používá jej celá řada programů v Unixu. Umožňují prohledávat soubory (grep, egrep), editovat je (sed, vi), analyzovat a vypočítávát zajímavé údaje (awk) či nabízejí plnohodnotný programovací jazyk, kde si můžete dělat, co vás napadne (Perl, Tk). Ale nebudeme se dlouho zdržovat propagandou a vzhůru do díla.

Jednoduché výrazy

Nejjednodušším regulárním výrazem je obyčejné písmeno - třeba r. Když se v textu hledá řetězec, který by tomuto regulárnímu výrazu vyhověl, hledá se jednoduše písmeno "r". Implicitně se (jak bývá v Unixu zvykem) rozlišují malá a velká písmena. Ve většině nástrojů však můžete tuto vlastnost vypnout.

Jelikož i v těch nejjednodušších případech člověk zpravidla hledá slovo a ne jediné písmeno, lze regulární výrazy řetězit. Použijete-li regulární výraz root, představuje vlastně zřetězení čtyř elementárních jednopísmenných regulárních výrazů. Výsledkem je chování, které byste očekávali - v textu se bude hledat slovo "root".

Vyhledávání jednoduchých slov je tou nejprimitivnější, ale zároveň nejčastější aplikací regulárních výrazů.

Příklad:
Řekněme, že hledáte nejčerstvější soubory v aktuálním adresáři. Nevím jak vy, ale já v hlavě nenosím, jak se jmenuje volba příkazu ls, která zajistí uspořádání podle času. Takže zadám man ls a následně si pomocí /time nechám vyhledat první výskyt slova "time". Nebudu-li spokojen, stisknu klávesu n a poskočím tak na další výskyt.

Popsané hledání založené na regulárních výrazech dovedou oba programy používané obvykle pro zobrazování manuálových stránek (a řady dalších textů): moreless. Tyto programy zároveň ilustrují jeden obecný princip: regulární výraz se typicky vyhledává jako podřetězec v jednotlivých řádcích textu.

Libovolný znak

Poměrně často dochází k situacím, kdy vám na určité části hledaného řetězce nezáleží. Například chcete ve zdrojovém textu HTML stránky vyhledávat začátky buněk v tabulkách - čili značky <TD> a <TH>. Až na třetí znak jsou oba řetězce shodné, takže je lze vyhledávat jediným regulárním výrazem. Pouze je třeba říci, že na jeho třetím znaku nezáleží.

Tuto činnost obstará znak tečka (.). Při hledání jí vyhoví libovolný znak kromě konce řádku. Nelze ji však ignorovat - nějaký znak jí program vždy musí přiřadit.

Příklad:
Výše zmíněné hledání řetězců "<TD>" či "<TH>" obstará regulární výraz <T.>. Přesněji řečeno mu vyhoví libovolný čtyřznakový řetězec, který začíná "<T" a končí znakem ">".

Ne až tak libovolný znak

Použitím tečky zcela rezignujete na hodnotu příslušného znaku. V některých případech se to hodí, jindy byste však potřebovali výběr omezit přísněji. Pak můžete sáhnout po hranatých závorkách.

Zapíšete-li do hranatých závorek skupinu znaků, bude tomuto regulárnímu výrazu vyhovovat právě jeden z těchto znaků. Například výrazu [xyz] vyhoví buď znak "x" nebo "y" nebo "z". Jestliže povolené znaky tvoří interval, můžete si ušetřit práci a v hranatých závorkách uvést pouze jeho meze, které spojíte pomlčkou.

Příklad:
Pro vyhledání libovolné číslice poslouží regulární výraz [0-9]. Předchozí hledání <TD> a <TH> bylo příliš benevolentní, protože za T povolovalo libovolný znak. Lepší je regulární výraz <T[DH]>, který se skutečně omezí jen na uvedené dvě značky.

Jednotlivých znaků a jejich intervalů můžete do hranatých závorek napsat, co hrdlo ráčí. Například výrazu [a0-9zl-nt] vyhoví libovolné z písmen a, l, m, n, t, z nebo libovolná číslice.

Kromě pomlčky se v hranatých závorkách vyskytuje ještě jeden speciální znak. Pokud hned za otevírací hranatou závorkou zapíšete stříšku (^), bude celá skupina negována. To znamená, že regulárnímu výrazu vyhoví libovolný znak odlišný od těch, které jsou uvedeny ve skupině. Například [^0-9] vyhoví cokoli kromě číslice.

Intervaly znaků vycházejí z kódování ASCII. To znamená, že například výrazu [a-z] vyhoví libovolné malé písmeno anglické abecedy. Doplnit velká písmena není žádný velký problém ([a-zA-Z]), ale s českými znaky je potíž. V některých programech najdete konstrukce, kterým vyhoví i znaky české abecedy, univerzálně platné elegantní řešení však neexistuje.

Speciální znaky

Možná už vás napadlo "ale co když potřebuji vyhledat tečku?" Tedy obecněji: jak vyřadit speciální význam některých znaků. Obecná odpověď na tuto otázku zní "zpětným lomítkem". V Unixu bývá zvykem, že pokud speciálnímu znaku předřadíte zpětné lomítko, vypnete tak jeho speciální chování (a v některých případech právě naopak, jak uvidíte později).

Příklad:
Celkem pohledný regulární výraz \.\.\. hledá tři tečky. Chcete-li vyhledat písmeno uzavřené v hranatých závorkách (tedy cosi jako "[x]"), použijte \[[a-z]\].

Uvnitř hranatých závorek panuje specifické prostředí. Tečka zde představuje obyčejnou tečku a význam ostatních dvou speciálních znaků lze potlačit prostým pořadím. Stříška představuje negaci jen pokud je uvedena na samotném začátku a pomlčka slouží jako oddělovač intervalu jen pokud má z obou stran jeho meze. Takže například výrazu [.^az-] vyhoví pouze jeden ze znaků ".", "^", "-", "a" nebo "z".

Pokud má být jedním z povolených znaků pravá hranatá závorka, uveďte ji hned za otevírací. Takže například regulárnímu výrazu [][] vyhoví levá nebo pravá hranatá závorka. Pokud byste znaky uvnitř vnějších hranatých závorek zapsali v opačném pořadí ([[]]), význam by se radikálně změnil: byl by interpretován jako [[] bezprostředně následované ]. Čili vyhověl by mu jedině řetězec "[]".

<-úvod další->

(c) Pavel Satrapa, 2000