Regulárne výrazy Tento dodatok obsahuje krátky, ale snáď dostatočný úvod do sveta regulárnych výrazov. Popisuje regulárne výrazy tak, ako ich používa &kate;. Tie sa líšia od regulárnych výrazov jazyka Perl aj od regulárnych výrazov príkazu grep. Úvod Regulárne výrazy umožňujú popísať nejaký text tak, aby ho bolo možné nájsť v texte aj v prípade, že to nie je vždy rovnaký text. Napríklad: Povedzme, že chceme nájsť text v odstavcoch, ktoré začínajú menami Henrik alebo Pernille a za nimi bude nejaký tvar anglického slovesa say. Normálne by ste hľadali najprv prvé meno Henrik, možno ešte s kúskom sa, asi takto: Henrik sa a každý nájdený výskyt by ste skontrolovali, či je na začiatku odstavca a či za písmenami sa slovo pokračuje says, said a tak podobne. No a potom by vás to isté čakalo v druhým menom... Pomocou regulárnych výrazov sa to dá urobiť jediným hľadaním a oveľa presnejšie. Aby sme to dosiahli, regulárne výrazy definujú pravidlá pre vyjadrenie detailov ale aj zobecnení textu. Náš príklad môžeme vyjadriť takto: Riadok začína buď Henrik alebo Pernille (za nimi môžu byť až 4 medzery alebo tabulátory), za ktorými je prázdne miesto a potom sa. Hneď za tým je ys alebo id. Zapíšeme ho týmto regulárnym výrazom: ^[ \t]{0,4}(Henrik|Pernille) sa(ys|id) Tento príklad ukazuje štyri hlavné koncepty moderných regulárnych výrazov: Vzorky Podmienky Kvantifikátory Spätné referencie Znak ^ (caret) na začiatku výrazu predstavuje podmienku, ktorá platí iba v prípade, že text, ktorý odpovedá zvyšku výrazu, je na začiatku riadku. Reťazce [ \t] a (Henrik|Pernille) sa(ys|id) sú vzorky. Prvý je trieda znakov, ktorá odpovedá medzere alebo horizontálnemu tabulátoru, druhá obsahuje najprv podvýraz pre Henrik alebo Pernille, potom kúsok zodpovedajúci práve textu sa a nakoniec podvýraz buď pre ys alebo id. Reťazec {0,4} je kvalifikátor, ktorý hovorí niečo medzi 0 až 4 opakovaniami toho, čo bolo predtým. Pretože reguálne výrazy podporujú koncept spätných referencií, môžete si zatvorením podvýrazu do zátvoriek uložiť nájdený text, je možné sa pri hľadaní na takto uložený text odvolávať. Dohromady výraz nájde práve to, čo sme chceli. Nasledujúce kapitoly detailne popisujú, ako vytvárať a používať vzorky, triedy znakov, podmienky, kvalifikátory a spätné referencie. Záverečná časť obsahuje niekoľko užitočných príkladov. Vzorky Vzorky obsahujú reťazce a triedy znakov. Vzorky môžu obsahovať podvzorky, čo sú vzorky v zátvorkách. Zápis špeciálnych znakov (escaping) Vo vzorkách a aj v triedach znakov majú niektoré znaky špeciálny význam. Aby ste ich mohli použiť priamo pre hľadanie, musia byť označené. Po anglicky sa tomu hovorí escaped. Softvér ich potom bude považovať za normálne znaky. To sa urobí tak, že na začiatok pridáte znak \ (spätné lomítko). Softvér pre spracovanie regulárnych výrazov potichu ignoruje takto zadané znaky tak, že im nedáva žiadny špeciálny význam v danom kontexte. Preto je možné takto zapísať napríklad aj j (\j). Ak neviete, či náhodou znak nemá špeciálny význam, môžete ho kľudne takho zapísať. Triedy znakov a skratky Trieda znakov je výraz, ktorý odpovedá jednému zo skupiny znakov. V regulárnych výrazoch sa definujú znaky, ktoré sú v triede, pomocou hranatých zátvoriek [] alebo pomocou niektorej zo skratiek uvedených nižšie. Jednoduché triedy znakov obsahujú iba jeden alebo viac znakov, napríklad [abc] (nájde buď písmeno a, b alebo c) alebo [0123456789] (odpovedá nejakej číslici). Pretože písmená a číslice sú usporiadané, môžete si ich zadanie skrátiť pomocou rozsahov: [a-c] je to isté ako [abc] a [0-9] znamená [0123456789]. Kombinácie, napríklad [a-fynot1-38] sú tiež povolené (tento príklad by samozrejme našiel a,b,c,d, e,f,y,n,o,t, 1,2,3 alebo 8). Veľké písmená sú niečo iné ako malé písmená. Aby ste vytvorili tiedu, v ktorej sa veľkosť písmen nerozlišuje, musíte napríklad pre a a b použiť [aAbB]. Je samozrejme možné vytvoriť aj obrátenú triedu, ktorá bude odpovedať všetkému, čo v triede nie je. Jednoducho pridajte na začiatok triedy ^: [^abc] nájde všetky znaky okrem a, b or c. Okrem normálnych znakov sú šte definované skratky, aby sa vám zjednodušil život: \a Toto odpovedá znaku zvonček z ASCII (BEL, 0x07). \f Toto odpovedá znaku konca stránky ASCII (FF, 0x0C). \n Toto odpovedá znaku koniec riadku z ASCII (LF, 0x0A, koniec riadku v systémoch Unix). \r Toto odpovedá znaku presun na začiatok z ASCII (CR, 0x0D). \t Toto odpovedá znaku horizontálny tabulátor z ASCII (HT, 0x09). \v Toto odpovedá znaku vertikálny tabulátor z ASCII (VT, 0x0B). \xhhhh Toto zodpovedá znaku Unicode, ktorého hexadecimálny kód je hhh (medzi 0x0000 až 0xFFFF). \0ooo (čiže \zero ooo) odpovedá znaku ASCII/Latin-1 s kódom v osmičkovej sústave ooo (medzi 0 a 0377). . (bodka) Toto zodpovedá ľubovoľnému znaku (aj konca riadku). \d Toto zodpovedá číslici. Rovnaké ako [0-9] \D Toto zodpovedá niečomu inému než číslici. Rovnaké ako [^0-9] alebo [^\d]. \s Toto zodpovedá znaku prázdneho miesta. Prakticky to isté ako [ \t\n\r] \S Toto zodpovedá normálnemu znaku. Prakticky to isté ako [^ \t\n\r] a rovnaké ako [^\s]. \w Zodpovedá ľubovoľnému znaku slova - v tomto prípade písmenu alebo číslici. Uvedomte si, že podtržítko(_) mu nezodpovedá (ako je to v jazyku Perl). Rovnaké ako [a-zA-Z0-9] \W Zodpovedá znaku, ktorý nie je v slovách - všetko okrem písmen a číslic. rovnaké ako [^a-zA-Z0-9] alebo [^\w] Skrátené triedy je možné vložiť do vlastných tried, napríklad pre nájdenie slova, medzery alebo bodky môžete použiť [\w \.] Zápis POSIX tried, čiže [:<meno triedy>:] momentálne nie je podporovaý. Znaky so špeciálnym významom v triedach znakov Tieto znaky majú v rámci [] špeciálny výraz a ich je nutné doplniť o spätné lomítko v prípade, že ich chcete priamo zahrnúť do triedy: ] Ukončí aktuálnu triedu. Neusí byť so spätným lomítkom v prípade, že je to prvý znak triedy (prípadne hneď za ^. ^ Označuje zápornú triedu, ak je to prvý znak. Ak ho chcete priamo hľadať a uviesť ako prvý znak, musíte ho použiť so spätným lomítkom. - (pomlčka) Obsahuje logický rozsah. \ (spätné lomítko) Znak pre escape znakov. Alternatívy: nájdenie <quote >jedno z</quote > Ak chcete nájsť jednu z niekoľkých možností, môžete ich oddeliť pomocou | (znak vertikálnej čiary). Napríklad pre nájdenie John alebo Harry môžete použiť výraz John|Harry. Pod-vzorky Podvzorky sú vzorky v zátvorkách a používajú sa na niekoľko vecí. Zadanie alternatív Môžete ich použiť pre zadanie skupiny alternatívnych možností. Jednotlivé možnosti sa oddeľujú znakom |. Napríklad pre nájdenie niektorého zo slov int, float alebo double môžete použiť vzorku int|float|double. Ak chcete nájsť iba jednu z týchto slov a za ním má byť medzera a nejaké písmená, uzavrite alternatívy do podvzorky: (int|float|double)\s+\w+. Zachytenie nájdeného textu (spätné referencie) Ak chcete používať spätné referencie, použite podvzorky na označenie časti, ktorú chcete zapamätať. Napríklad, ak chcete nájsť dva výskyty jednoho slova oddelené čiarkou a prípadne nejakými medzerami, môžete napísať (\w+),\s*\1. Podvzorka \w+ nájde zhluk písmen a celý výraz bude odpovedať ak za nimi bola čiarka, 0 alebo viac medzier a potom rovnaký zhluk znakov. (Reťazec \1 označuje prvú podvzorku v zátvorkách) Prečítajte si aj kapitolu Spätné referencie. Dopredné podmienky Dopredné podmienky sú podvzorky začínajúce ?= alebo ?!. Napríklad, ak chcete nájsť Bill ale iba ak za ním nie je Gates, môžete použiť tento výraz: Bill(?! Gates). (Toto nájde Bill Clinton a aj Billy the kid, ale ostatné výskyty to bude ignorovať.) Podvzorky používané pre podmienky sa nepamätajú. Prečítajte si aj kapitolu Podmienky. Znaky, ktoré majú špeciálny význam vo vzorkách Vo vzorkách majú tieto znaky špeciálny význam, takže pre ich priame hľadanie ich musíte doplniť spätným lomítkom. \ (spätné lomítko) Znak pre escape. ^ Podmienka pre začiatok reťazca. $ Podmienka pre koniec reťazca. () (ľavá a pravá zátvorka) Označuje podvzorky. {} (ľavá a pravá zložená zátvorka) Označuje číslené kvalifikátory. [] (ľavá a pravá hranatá zátvorka) Označuje triedy znakov. | Logické OR. Oddeľuje alternatívy. + (plus) Kvalifikátor, 1 alebo viac. * (hviezdička) Kvalifikátor, 0 alebo viac. ? (otáznik) Nepovinný znak. Dá sa chápať ako kvalifikátor 0 alebo 1. Kvantifikátory Kvantifikátory umožňujú, aby regulárny výraz zodpovedal danému počtu alebo bol v danom rozsahu opakovaní znaku, triedy alebo podvzorky. Kvantifikátory sú uzavreté v zložených zátvorkách ({ a }) a majú tvar {[minimálne-výskytov][,[maximálne-výsktytov]]} Použitie sa najlepšie vysvetlí na príklade: {1} Presne jeden výskyt {0,1} Jeden alebo žiadny výskyt {,1} To isté ale menej písania :-) {5,10} Aspoň 5 ale maximálne 10 výskytov. {5,} Aspoň 5 výskytov, žiadne obmedzenie zhora. Okrem toho existujú aj skratky: * (hviezdička) podobné ako {0,}, nájde ľubovoľný počet opakovaní. + (plus) podobné ako {1,}, aspoň jeden výskyt. ? (otáznik) podobné ako {0,1}, 0 alebo 1 výskyt. Greed Ak používate kvantifikátory bez maximálnej hodnoty, regulárne výrazy sa štandardne snažia nájsť čo najviac zodpovedajúceho textu. Tomu sa často hovorí greedy chovanie. Moderné regulárne výrazy poskytujú spôsob, ako toto chovanie vypnúť. Napríklad v dialógu pre hľadanie je voľba Minimálne hľadanie, ktoré označuje, či sa má hľadať takto maximalisticky. Príklady zo života Tu je pár príkladov využitia kvantifikátorov ^\d{4,5}\s Zodpovedá čísliciam v 1234 go a 12345 now, ale nie v 567 eleven ani v 223459 somewhere \s+ Odpovedá jednému alebo viacerým prázdnym znakom (bla){1,} Zodpovedá všetkým blablabla a bla v blackbird alebo tabla. /?> Zodpovedá /> v <closeditem/> ako aj > v <openitem>. Podmienky Podmienky umožňujú, aby regulárne výrazy zodpovedali iba za zadaných podmienok. Podmienka nemusí zodpovedať znaku. Skôr overuje okolie, či v nom niečo platí. Napríklad hranica slov sa nesnaží nájsť písmeno nepatriace slovu na svojej druhej strane. Namiesto toho overí, že tam nie je znak slova. To znamená, že podmienka bude platiť aj tam, kde žiadny znak nieje, napríklad na konci prehľadávaneho reťazca. Niektoré podmienky obsahujú vzorky, ktorým majú zodpovedať, ale nájdený text sa nestane súčasťou výsledku celého výrazu. Regulárne výrazy, ktoré tu popisujeme, podporujú tieto podmienky: ^ (začiatok reťazca) Zodpovedá začiatku prehľadávaného reťazca. Výraz ^Peter bude zodpovedať Peter v reťazci Peter, hey!, ale nie v Hey, Peter! $ (koniec reťazca) Zodpovedá koncu prehľadávaného reťazca. Výraz you\?$ nájde posledné you v reťazci You didn't do that, did you? ale žiadne v You didn't do that, right? \b (okraj slova) Platí, ak je na jednej strane znak slova, ale na druhej nie. To sa hodí pre nájdenie koncov slov, napríklad na oboch koncoch slova musí platiť. Výraz \bin\b nájde samostatné in v reťazci He came in through the window, ale nie in v slove window. \B (nie okraj slova) Platí, ak neplatí \b. To znamená, že bude napríklad zodpovedať v slovách: Výraz \Bin\B bude nájdený v window ale nie v integer alebo I'm in love. (?=VZORKA) (Pozitívny výhľad) Podmienka výhľadu sa pozrie na reťazec, ktorý nasleduje za možným výskytom. Pozitívny výhľad zabráni, aby sa našiel text, ktorý by nezodpovedal VZORKA, ale text, ktorý vzorke zodpovedá, sa vo výsledku neobjaví. Výraz auto(?=\w) zodpovedá auto v autobus ale nie v To auto je pokazené. (?!VZORKA) (Negatívny výhľad) Negatívny výhľad zabráni nájdeniu textu v prípade, že nasledujúci text nezodpovedá VZORKA Výraz const \w+\b(?!\s*&) bude zodpovedať na const char v reťazci const char* foo ale nie const QString v const QString& bar, pretože & zodpovedá vzorke negatívneho výhľadu. Spätné referencie