Internet Info, s.r.o. Lupa Měšec Podnikatel Root Zdroják DigiZone Slunečnice Vitalia TopDrive KupDnes Navrcholu NovýTarif Dobrý web Weblogy Woko Jagg Computer.cz SK: MojeLinky

Hlavní navigace

Regulární výrazy (7)

Na poslední díl našeho seriálu jsem si pošetřil speciality jazyka Perl. Pokud se vám při zahlédnutí jména Perl povážlivě zvedá hladina adrenalinu, podívejte se alespoň na konec článku. Najdete tam odkazy na literaturu a srovnávací tabulku speciálních znaků, kteréžto materiály by se vám mohly hodit.

Tweetni to Twitter Jaggni to! Jagg Del.icio.us Delicious

Perl je do značné míry srdeční záležitost. Znám řadu jeho vášnivých zastánců a zrovna tak jeho zuřivé odpůrce. Ten jazyk je pohledem teoretika mimořádně odporný, ale zároveň neuvěřitelně mocný a praktický. Docela výstižně (a velmi vtipně) to myslím vyjádřil Jeffrey E. F. Friedl ve své knize o regulárních výrazech:

Síla Perlu může být ničivou zbraní v rukách zkušeného uživatele, zdá se však, že v Perlu sbíráte zkušenosti tak, že se opakovaně střílíte do nohy.

Dnes se ale nehodlám věnovat jazyku jako takovému. Raději se soustředím na jeho speciality v oboru regulárních výrazů. A v tomto směru je v současnosti jasná jednička, ať se to jeho odpůrcům líbí nebo ne.

Uvolněná syntax

Regulární výrazy jsou velmi kondenzované, což je bohužel činí obtížně srozumitelnými. Obecně si troufám prohlásit, že regulární výraz je často snadnější vytvořit než jej sám po sobě pochopit.

Do jazyka Perl (přesněji řečeno do verze 5, ale ta už je na světě pět let, takže ji lze považovat za standard jazyka) proto přibyla možnost rozvolnění zápisu regulárních výrazů. Nepřidává žádné nové konstrukce, jen je umožňuje srozumitelně zapsat.

Uvolněnou syntax zapíná volba x v operátoru pro hledání či nahrazování (operátory m a s). Regulární výraz se pak zapisuje do složených závorek podobně jako blok programu, ignorují se v něm mezery a konce řádků (pokud jim nepředchází zpětné lomítko) a komentáře zahájené znakem #.

Příklad:

V části o zapamatování jste se mohli setkat s nechutnou substitucí

s/([^:]*):([^­:]*:){3}([^:]*)­.*/<A HREF=„/~\1“>\3<\/A­>/

která z řádků v /etc/passwd vyráběla seznam domácích stránek uživatelů. S využitím uvolněné syntaxe bychom ji mohli přepsat následovně:

s{

   ([^:]*): ( #přihlašovací jméno (1))

   ([^:]*:){3} ( #přeskočíme heslo, UID a GID)

   ([^:]*) ( #vlastní jméno (3))

   .* ( #přeskočíme zbytek)

}{<A HREF=„/~­\1“>\3</A>}x

Nepřipadá vám to o dost srozumitelnější? Upozorňuji, že uvolněná syntax se týká pouze regulárního výrazu, nikoli nahrazujícího řetězce. V něm se projeví pouze tím, že je uzavřen do složených závorek.

Drobnosti, které potěší

Perl nabízí řadu konstrukcí, které sice nepřinášejí nějakou zásadní inovaci stran schopností regulárních výrazů, ale v běžném životě silně potěší. Asi nejčastěji používané jsou kategorie znaků. Z těch nejběžnějších lze jmenovat:

Zápis Význam Odpovídá
\d číslice [0–9]
\D nečíslice [^\d]
\w alfanumerický znak [a-zA-Z0-9]
\W nealfanumerický znak [^\w]
\s prázdný znak [\ \t\n\r]
\S neprázdný znak [^\s]

Tyto speciální znaky celkem výrazně přispívají ke srozumitelnosti regulárních výrazů. Navíc pokud svůj program zahájíte příkazem use locale, budou mezi alfanumerické znaky zařazeny i akcentované znaky národní abecedy.

Příklad:

Výměnu prvních dvou slov na řádku pak zajistí celkem mírumilovný příkaz

s/(\w+)(\W+)(­\w+)/\3\2\1/

Kromě Perlu už převzaly podobné znakové kategorie i současné verze dalších nástrojů (konzultujte s dokumentací). Kromě nich je leckde podporován i zápis kategorií podle POSIXu, kde se například číslice zapisuje jako [:digit:], alfanumerický znak jako [:alnum:] a prázdné místo [:space:]. Tyto kategorie se však zapisují mezi [], takže například řádek začínající číslicí se vyjádří pomocí ^[[:digit:]], což už má k eleganci poměrně daleko (totéž v Perlu: ^\d). Perl POSIXové kategorie nepodporuje.

Syté (též líné) opakování pomůže řešit problémy s nadměrnou žravostí opakovacích konstrukcí. Zapisuje se jednoduše: za opakovací znak (*, +, ? či {min,max}) připojíte otazník. Přípustný počet opakování se tím nijak nezmění, ale na rozdíl od klasické varianty se snaží, aby opakování bylo co nejméně. Takže třeba oblíbený řetězec v uvozovkách lze hledat pomocí „.*?“. Je to přehlednější, ale pomalejší než obvyklé řešení „[^“]*".

Třetí užitečnou drobností jsou závorky bez zapamatování. Slouží výlučně k vymezení části regulárního výrazu (např. pro opakování nebo omezení působnosti „nebo“). Vyhovující řetězec se neukládá, takže vám ubyde špetka starostí při počítání indexů těch zapamatovaných. Tyto speciální závorky se zapisují ve tvaru (?:).

Příklad:

Ještě jednou přepracuji příklad pro transformaci řádku z /etc/passwd na položku v seznamu domácích stránek. S využitím popsaných konstrukcí by mohl vypadat takto:

s{

   (.*?): ( #přihlašovací jméno (1))

   (?:.*?:){3}( #p­řeskočíme heslo, UID a GID)

   (.*?): ( #vlastní jméno (2))

   .* ( #přeskočíme zbytek)

}{<A
HREF=„/~\1“>\­2</A>}x

Tentokrát se v části přeskakující heslo, UID a GID vyhnu zapamatování, takže pod čísly 1 a 2 mám uloženy skutečně jen ty informace, které mne zajímají. Dvojtečka z konstrukce (?: se v tomto případě bohužel nepěkně plete s oddělovačem položek, ale s tím se nedá nic dělat. Líné opakování mi umožnilo poněkud zjednodušit výrazy pro jednotlivé části řádku.

Vyhlížení

Dost silný nástroj pro některé speciální případy nabízí tak zvané vyhlížení (anglicky lookahead). Existuje ve dvou odrůdách: pozitivní vyhlížení se zapisuje v podobě (?=výraz) a je splněno, pokud následující část řetězce vyhovuje výrazu. Negativní vyhlížení (?!výraz) naopak uspěje, pokud výrazu nevyhovuje. Důležité je, že vyhlížení se jen podívá, zda se vzor dá či nedá najít, ale neposouvá zkoumanou pozici dál (jemu odpovídající řetězec je vždy prázdný).

Příklad:

Vzoru \d+(?= Kč) vyhoví neprázdná posloupnost číslic, ale jen pokud za ní následuje řetězec „ Kč“. Ten však sám o sobě není zahrnut do vyhovujícího řetězce. Takže pokud příkaz

s/(\d+)(?= Kč­)/???/g

vypustíte na řetězec

Párátka 20 CX Turbo za 25 Kč kus

obdržíte výsledek

Párátka 20 CX Turbo za ??? Kč kus

Za příklad negativního vyhlížení může posloužit (?!000)\d\d\d, kterému vyhoví libovolná trojice číslic s výjimkou 000.

Faktem je, že vyhlížení není principiálně nezbytné. Zpravidla je lze nahradit jinými konstrukcemi jazyka. Například zachování „ Kč“ za skupinou číslic by se dalo zařídit pomocí zapamatování. Test na trojici číslic, ne však 000 by se dal rozložit do dvou nezávislých testů a podobně. V některých případech však vyhlížení dává zajímavé možnosti.

Příklad:

Hezkou vychytávkou využívající vyhlížení je oddělování řádů ve velkých číslech. Mezi trojice číslic se mají vložit mezery, takže z „12345678“ vznikne „12 345 678“. Vtip je v tom, že se trojice počítají odzadu, na což regulární výrazy nejsou příliš zařízené. Vyhlížení umožňuje následující řešení:

s{

   (\d{1,3}) ( #za první s­kupinu patří me­zera)

   (?= ( #ale jen když následuje)

      (?:\d\d\d)+ (
 #alespoň jedna trojice číslic)

      (?!\d) ( #a tím číslo končí)

   ) ( )

}{\1 }gx

Díky vyhlížení se můžete přesvědčit, že počet číslic, které následují za aktuální pozicí ve zpracovávaném řetězci, je násobkem tří. Vyhlížení zároveň zajistí, že se tato pozice nezmění a že se při příštím opakování (díky volbě g se provádí pro všechny výskyty) se bude pokračovat za naposledy vloženou mezerou.

Literatura

Pokud je mi známo, vyšla zatím jediná kniha věnovaná výlučně regulárním výrazům. Napsal ji Jeffrey E. F. Friedl a jmenuje se Mastering Regular Expressions (vydalo nakladatelství O'Reilly & As­sociates v roce 1997, ISBN 1–56592–257–3). Není to pochopitelně vyslovená oddechovka, ale v rámci možností vysvětluje vlastnosti regulárních výrazů, vhodné a nevhodné techniky pro jejich vytváření. Vzhledem k rozsahu přes 300 stran si může dovolit jít dost do hloubky.

TIB2012

       

Cenné služby odvede kniha Unix Power Tools, jejímiž autory jsou Jerry Peek, Tim O'Reilly a Mike Loukides. Vyšla také u O'Reilly & As­sociates v roce 1997 (2. vydání, ISBN 1–56592–260–3). Obsahuje velmi slušnou kapitolu o regulárních výrazech a kromě ní řadu tipů a triků na využívání programů, které s nimi pracují. Osobně ji považuji za jednu z nejpřínosnějších knížek, které jsem kdy měl v ruce.

Přehledová tabulka

Jako závěrečnou přílohu vám nabízím stručný přehled regulárních výrazů v nejběžnějších nástrojích. Konkrétně se jedná o GNU grep a egrep verze 2.3, GNU awk verze 3.0.4, vim verze 5.5 a Perl verze 5.005_03. Tabulka je k dispozici v těchto formátech: PostScript, PDF, HTML.

Školení: TCP/IP síť na Linuxu II

V tomto školení prohloubíte svoji znalost síťování na Linuxu a vyzkoušíte si pokročilejší techniky. Školení je určené mimojiné i pro správce poskytovatelských sítí.

  • Průřez technologiemi TCP/IP 
  • Stavba testovací sítě
  • Dynamický routing: OSPFv2 a OSPFv3
  • Bridging, proxy ARP, proxy NDP
  • Různé metody překladu adres
  • NAT traversal v praxi
  • Přepis paketů
  • Tunelování a VPN
  • Troubleshooting, situace z praxe

Podrobnější informace a přihláška 

Ohodnoťte jako ve škole:
Průměrná známka 2,92

Přehled názorů

Az doted jsem vydrzel. Dnesnim...
Jan Pruner 1. 6. 2000 11:17
Nový
└ 
Re: Az doted jsem vydrzel. Dnesnim...
pan Pára 12. 5. 2009 15:07
Nový
Perl 5.6.0 uz ma i POSIX tridy...
Stepan Roh 2. 6. 2000 11:23
Nový
Uzitecna tabulka, ale chybi mi...
Tomas Zellerin 2. 6. 2000 14:03
Nový
To je fakt, sed by se taky hod...
RWS 9. 6. 2000 16:35
Nový
Mam maly problem. Pro nekoho m...
Martin Michale 14. 6. 2000 18:12
Nový
:-o
jirka 7. 9. 2003 17:49
Nový
spojení řádku
Zdenek 9. 7. 2004 16:17
Nový
└ 
Re: spojení řádku
ordan 21. 9. 2004 12:55
Nový
 
└ 
Re: spojení řádku
Andrej Kvasnica 17. 2. 2005 09:34
Nový
 
 
└ 
Re: spojení řádku
Andrej Kvasnica 17. 2. 2005 11:19
Nový
hledani vyce slov ve vsech souborech v adresari pomoci perlu ...
bany 19. 5. 2010 19:55
Nový
       

Tento text je již více než dva měsíce starý. Chcete-li na něj reagovat v diskusi, pravděpodobně vám již nikdo neodpoví. Pro řešení aktuálních problémů doporučujeme využít naše diskusní fórum.

Zasílat nově přidané příspěvky e-mailem