Obcování s ďáblem 17: Regulární výrazy - MujMAC.cz - Apple, Mac OS X, Apple iPod

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:

Seriály

Více seriálů



Software

Obcování s ďáblem 17: Regulární výrazy

15. listopadu 2001, 00.00 | Dnešní díl bude tak trošku teoretický. Namísto toho, abychom si ukázali nějaké konkrétní příkazy a jejich využití, budeme se zabývat regulárními výrazy. Časem ale uvidíte, že existuje dlouhá řada případů, kde je znalost regulárních výrazů k
nezaplacení.

Dnešní díl našeho seriálu bude tak trošku teoretický — namísto toho, abychom si ukázali nějaké konkrétní příkazy a jejich využití, budeme se zabývat regulárními výrazy. Časem ale uvidíte, že existuje dlouhá řada případů (my se seznámíme jen s některými z nich), kde je znalost regulárních výrazů k nezaplacení.

Co to vlastně je?

Regulární výraz je textový řetězec, který podle určitých pravidel (jimiž se budeme právě dnes zabývat) dělí všechny možné ostatní textové řetězce do dvou skupin: na ty, jež danému regulárnímu výrazu odpovídají (neboli v programátorském slangu "mačují" z anglického "match"), a na ty ostatní.

My jsme se už s něčím podobným setkali: připomeňme si třetí díl, ve které jsme se naučili určovat specifikace souborů v shellu s využitím hvězdiček a hranatých závorek. Regulární výrazy fungují velmi podobně; nabízejí však mnohem bohatší paletu možností.

A k čemu je to dobré?

Samozřejmě, základní službou, ke které se regulární výrazy používají, je vyhledávání textů: hledání všech řádků v dokumentu, na kterých se vyskytuje text, který odpovídá danému regulárnímu výrazu; hledání všech takových řetězců a záměna jinými a podobně.

Představte si, že máte rozsáhlý projekt, ve kterém se v mnoha zdrojových souborech používá volání funkce "ellipse(x,y,r1,r2)" — kde samozřejmě x, y, r1 a r2 jsou obecné výrazy, určující střed elipsy a oba její poloměry. Na nových knihovnách se třeba objeví nová služba "circle(r,x,y)", která je mnohem efektivnější; chtěli bychom proto předělat všechna volání "ellipse" ve kterých je r1 stejné jako r2 na volání "circle" — nejenže musíme ověřit, zda je r1 a r2 stejné, ale navíc musíme změnit pořadí argumentů a jeden z nich vypustit. Bez regulárních výrazů bychom to museli dělat ručně; s nimi je to poměrně snadné.

Nebo jiný příklad: vzhledem k tomu, že server MujMac není schopen akceptovat standardní HTML entity, nemohu pro psaní těchto článků použít přímo HTML editor. Píši je proto jako obyčejný ASCII text, a HTML tagy vkládám automaticky. Je-li např. za sebou řada odstavců, jež nejsou odděleny prázdnou řádkou, a každý z nich začíná znakem '-', převede se takový text na HTML seznam (<UL>...</UL>). S využitím editoru sed a regulárních výrazů je to snadné; jinak bych si na to musel psát poměrně komplikovaný převodní program...

Základní výrazy

Základní regulární výrazy vždy odpovídají jednomu znaku. Např. jeden z nejjednodušších regulárních výrazů je "a" — ten odpovídá právě znaku 'a' a žádnému jinému. Podobně jako u souborů v shellu můžeme i zde použít třeba "[abc]" pro kterýkoli ze znaků 'a', 'b' nebo 'c'.

Jakýkoli znak vyjma speciálních

Základní regulární výraz, který neobsahuje nic jiného než obyčejný znak ("a", "X", " ",...) odpovídá právě tomuto znaku, a ničemu jinému.

Seznam speciálních znaků bohužel trochu závisí na konkrétní aplikaci, jež regulární výrazy interpretuje. Vždy však mezi speciální znaky patří '.', '[', '*' a '\'; často také '$', '^', '?', '+', '{', '(' a ')'. Naopak, nikdy mezi speciální znaky nepatří písmena a čísla. Pokud jsme na pochybách, nejjednodušší je to jednou vyzkoušet (nebo se podívat do nápovědy man).

V každém případě chceme-li sestavit regulární výraz, který odpovídá některému ze speciálních znaků, použijeme před ním "escape" znak '\'. Regulární výraz, který odpovídá tečce, tedy vypadá takto: "\."; chceme-li najít hvězdičku, můžeme použít regulární výraz "\*".

Seznam alternativ

Podobně jako v shellu, můžeme i v regulárních výrazech použít seznam znaků v hranatých závorkách; takový regulární výraz odpovídá kterémukoli z vyjmenovaných znaků. Chceme-li tedy napsat regulární výraz, jemuž odpovídají právě znaky 'a', 'b', 'c' nebo 'd', můžeme použít "[abcd]".

Regulární výrazy nabízejí řadu fint pro snazší určení takovýchto seznamů. Prvním z nich je to, že můžeme použít pomlčku ve významu "od - do": namísto regulárního výrazu "[abcd]" z minulého příkladu bychom mohli napsat ekvivalentní "[a-d]". V tomto konkrétním případě je to samozřejmě téměř lhostejné; málokomu by se však asi chtělo rozepisovat bez této možnosti regulární výraz pro jakékoli písmenko nebo číslo "[a-zA-Z0-9]"!

Chceme-li "mečovat" všechny znaky kromě známého seznamu, stačí hned za první hranatou závorku zapsat znak '^': regulárnímu výrazu "[^0-9a-fA-F]" např. odpovídají právě všechny znaky, které není možné použít v zápisu hexadecimálního čísla.

Pro některé často používané množiny znaků dokonce existují speciální jména. Ta vždy začínají dvojicí "[:" a končí dvojicí ":]", aby se dala dobře rozeznat:

  • "[:alpha:]" pro písmenka, "[:digit:]" pro číslice, a "[:alnum:]" pro obojí (takže regulární výrazy "[[:alnum:]]" a "[[:digit:][:alpha:]]" jsou ekvivalentni);
  • "[:xdigit:]" pro znaky, odpovídající hexadecimálním číslicím;
  • "[:space:]" pro oddělovače;
  • řadu dalších, ne tak často využívaných možností může zájemce najít v nápovědě man grep.

Povšimněte si, že hranaté závorky ve jménech množin znaků nemají nic společného s hranatými závorkami, jež representují seznam alternativ — zatímco tedy regulární výraz "[[:alpha:]]" odpovídá libovolnému písmenu, regulární výraz "[:alpha:]" by odpovídal jen znakům ':', 'a', 'l', 'p' nebo 'h'!

Je třeba se znímit ještě o tom, že uvnitř hranatých závorek neplatí speciální znaky (např. tečka zde representuje prostě tečku, hvězdička hvězdičku atd.), že znak '^' můžeme vložit do seznamu pokud nebude první, znak ']' naopak pokud bude první, a znak '-' pokud bude poslední. Např. "[]^-]" je tedy regulární výraz, kterému odpovídá kterýkoli ze znaků ']', '^' nebo '-' — ani jeden z nich zde nemá svůj speciální význam, popsaný výše.

Žolík

Tečka má v regulárních výrazech stejný význam, jaký měl otazník ve jménech souborů v shellu: regulárnímu výrazu "." může odpovídat libovolný znak.

Zatracený Mistr Jan!

Hned na začátku je třeba upozornit, že bohužel regulární výrazy (tak, jak jsou k dispozici v řadě standardních příkazů) se nedokáží moc dobře vyrovnat se znaky s diakritickými znaménky. Regulární výraz "[a-z]" tedy rozhodně nebude odpovídat třeba znaku 'č' nebo znaku 'á'; o nic lepší to nebude ani s výrazem "[[:alpha:]]".

Ostatně ani v Terminálu nemůžeme standardně používat ne-ASCII znaky: někdy (např. v příkazu tr) bychom je mohli vkládat pomocí jejich kódů, jindy není možné ani to. Bohužel, nic se s tím nedá dělat: když byl před desítkami let Unix se svými příkazy navrhován, pracovalo se se základní šestadvacetipísmenkovou abecedou, a o ničem jiném se nikomu ani nesnilo.

Samozřejmě, že časem budou tato omezení mizet, ale počkáme si na to hezky dlouho...

Příště...

...si ukážeme několik speciálních výrazů, a vysvětlíme si že, jak a hlavně proč mohou některé regulární výrazy odpovídat i prázdnému řetězci.

Obsah seriálu (více o seriálu):

Tématické zařazení:

 » Rubriky  » Informace  

 » Rubriky  » Agregator  

 » Rubriky  » Tipy a Triky  

 » Rubriky  » Začínáme s  

 » Rubriky  » Software  

 

 

 

Nejčtenější články
Nejlépe hodnocené články
Apple kurzy

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: