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:
Tipy a Triky
Obcování s ďáblem 19: Skládání regulárních výrazů
29. listopadu 2001, 00.00 | Ve dvou minulých dílech jsme se seznámili se základními kameny regulárních výrazů. Dnes pronikneme dále do tajů a vysvětlíme si další možnosti využití - skládání, opakování a další.
Ve dvou minulých dílech jsme se seznámili se základními kameny regulárních výrazů: předminule jsme si ukázali tři nejjednodušší výrazy, odpovídající jednotlivým znakům, a minule jsme si doplnili několik speciálních výrazů, jež odpovídají povětšinou prázdnému řetězci.Například takový regulární výraz "\B" odpovídá prázdnému řetězci, který není na okraji slova; to tedy znamená, že výraz ".\B." bude odpovídat buďto dvojici písmen uvnitř slova, nebo dvojici oddělovačů: jen v těchto případech mezi oběma znaky (representovanými tečkami, a tedy vlastně libovolnými) nebude "prázdný řetězec na hranici slova"!
Skládání vedle sebe
Ačkoli jsme se o tom explicitně nezmínili, skládání regulárních výrazů vedle sebe (někdy se používá pojem "řetězení", ale já jej nemám rád) vlastně už nějakou dobu používáme. Řekneme-li honosně (a nesrozumitelně), že
- regulárnímu výrazu vzniklému složením výrazů <r1><r2> vedle sebe odpovídají právě všechny textové řetězce, které lze sestavit složením libovolného řetězce, odpovídajícího výrazu <r1> s libovolným řetězcem, odpovídajícím výrazu <r2>
, jen jsme formalizovali zřejmý a srozumitelný fakt, že když regulárnímu výrazu "a" odpovídá znak 'a' a regulárnímu výrazu "b" znak 'b', pak regulárnímu výrazu "ab" bude nejspíš odpovídat řetězec "ab". Nebo že regulárnímu výrazu "h...o" bude odpovídat jakýkoli pětiznakový řetězec, který začíná znakem 'h' a končí znakem 'o' — například "he lo" ve známé písničce "Ohe ohe lodnici".
Závorky
Jakýkoli regulární výraz můžeme uzavřít do závorek, a na skupině textových řetězců, jež mu odpovídají, se tím nic nezmění. S tím, co známe dosud, by nám to nebylo celkem k ničemu; hned s několika následujícími operátory se to ale každou chvíli hodí.
Zde je třeba si dát pozor na to, že některé aplikace pracují s tzv. rozšířenými ("extended") regulárními výrazy, a ty pak považují závorky za speciální znak (např. egrep). Jiné aplikace však využívají tzv. základních ("basic") regulárních výrazů, a pro ty závorky speciálním znakem nejsou (příkladem může být grep nebo vyhledávání podle regulárních výrazů v ProjectBuilderu).
Pracujeme-li s rozšířenými regulárními výrazy, musíme použít znak '\' chceme-li zadat výraz, který odpovídá závorce; v základních naopak znak '\' přepne "normální znak závorka" na "speciální znak — závorka pro uzavírání výrazů".
Jinými slovy, regulární výraz, který odpovídá znaku '(' a sám je jako regulární výraz uzávorkován, bude v různých aplikacích vypadat různě:
- v příkazu grep: "\((\)"
- v příkazu egrep: "(\()"
Nelekejte se, prosím — je to složité jen na první pohled. Původně prostě existovaly jednoduché (základní) regulární výrazy, ve kterých závorky nebyly k dispozici. Pak přibyly nové služby a závorky; pro zachování kompatibility s existujícími příkazy se původní služby ponechaly beze změny pod názvem "základní", a nové přibyly jako "rozšířené".
Nakonec byly všechny nové služby rozšířených regulárních výrazů přidány i do základních, ale "se zpětným lomítkem": tak už není mezi základními a rozšířenými regulárními výrazy žádný rozdíl v nabízených službách, ale v pohodlnosti:
- v jednodušších příkazech se regulární výrazy závorkují jen výjimečně; je proto pro uživatele velmi pohodlné, může-li znak '(' zadávat rovnou, bez zpětných lomítek. Když už jednou za dlouhý čas chce nějaký regulární výraz uzávorkovat, zpětná lomítka tolik nevadí. Použijeme tedy s výhodou základní regulární výrazy (např. prostřednictvím příkazu grep);
- pro složité regulární výrazy, ve kterých se hodně závorkuje, je tomu právě naopak: je šikovné a pohodlné, můžeme-li to dělat bez zpětných lomítek; chceme-li občas zadat závorku jako obyčejný znak, zpětné lomítko už tolik nevadí. Použijeme tedy s výhodou rozšířené regulární výrazy (např. prostřednictvím příkazu egrep).
Kromě závorek totéž platí i pro některé další speciální znaky, jejichž využití je popsáno níže ('?', '+', '{', a '|').
Opakování
Mezi nejčastěji využívané služby regulárních výrazů bezpochyby patří opakování: můžeme sestavit nový regulární výraz tak, že vezmeme nějaký již existující, a určíme kolikrát se má či nemá opakovat. V regulárních výrazech to určují operátory, umístěné za daný výraz — např. výraz "a{5}" znamená "pětkrát opakuj 'a'", a je tedy ekvivalentní regulárnímu výrazu "aaaaa".
Operátory opakování jsou:
- "?" nanejvýše jednou;
- "*" libovolný počet opakování;
- "+" nejméně jednou;
- "{N}" právě N-krát;
- "{,M}" nejvýše M-krát;
- "{N,}" nejméně N-krát;
- "{N,M}" nejméně N-krát a nejvýše M-krát.
Operátory opakování mají vyšší prioritu než skládání vedle sebe — regulární výraz "ab*" tedy odpovídá řetězci, který začíná písmenem 'a', za nímž následuje libovolný počet 'b'éček. Pokud bychom chtěli řetězec, složený z libovolného počtu dvojic "ab", můžeme použít závorky, popsané v minulém odstavci: "(ab)*".
Operátor "?" representuje nepovinnost: chceme-li např. sestavit regulární výraz, kterému odpovídají textové řetězce "OS X" i "OSX", můžeme použít třeba výraz "OS ?X", kde je operátor "?" aplikován na mezeru.
Snad nejčastěji je v regulárních výrazech používána kombinace ".*", která odpovídá hvězdičce ve specifikaci souborů shellu: libovolné množství libovolných znaků. Regulárnímu výrazu příkazu grep "(.*)" tedy odpovídá "cokoli v závorkách" (připomeňme minulý odstavec: v příkazu egrep by ekvivalentní regulární výraz vypadal trochu jinak — "\(.*\)").
Alternativy
Pomocí speciálního operátoru "|" můžeme spojit dva regulární výrazy, jež považujeme za alternativy: celkovému výrazu bude odpovídat libovolný řetězec, který odpovídá kterémukoli z obou výrazů.
Operátor má nižší prioritu než skládání vedle sebe: regulární výraz, jemuž budou odpovídat řetězce "ahoj" a "nazdar", tedy je prostě "ahoj|nazdar".
To je pro dnešek vše
Příště se seznámíme už s poslední, ale snad nejsilnější, vlastností regulárních výrazů — ukážeme si možnost práce se zpětnými odkazy výrazu na části sebe sama.
Obsah seriálu (více o seriálu):
- Obcování s ďáblem
- Obcování s ďáblem 2 - základy
- Obcování s ďáblem 3 - Práce se soubory
- Obcování s ďáblem 4 - Další práce se soubory
- Obcování s ďáblem 5 - Stále soubory, hlavně linky
- Obcování s ďáblem 6: Pár zbývajících drobností
- Obcování s ďáblem 7: Samá voda, přihořívá, hoří!
- Obcování s ďáblem 8: Jak se do shellu volá, tak se program ozývá
- Obcování s ďáblem 9: Nové finty na programy
- Obcování s ďáblem 10: Do fronty, pánové, do fronty!
- Obcování s ďáblem 11: Standardní vstup a výstup
- Obcování s ďáblem 13: Další triky
- Obcování s ďáblem 14: Vyšší škola hledání souborů
- Obcování s ďáblem 15: Příkaz find stokrát jinak
- Obcování s ďáblem 16: Co se ještě dá uvařit z příkazu find
- Obcování s ďáblem 17: Regulární výrazy
- Obcování s ďáblem 18: Speciální regulární výrazy
- Obcování s ďáblem 19: Skládání regulárních výrazů
- Obcování s ďáblem 20: Regulární výrazy se zpětnými odkazy
- Obcování s ďáblem 21:K čemu je dobrý grep...
- Zázraky ihned, nemožné na počkání: sed
- Obcování s ďáblem - další finty s příkazem sed
- Rozsáhlejší příklad se sedem
- Obcování s ďáblem: Další kouzla, aneb awk
- Awk a proměnné
- Obcování s ďáblem 27: Awk a výrazy
- Obcování s ďáblem: Awk a funkce
- Awk a příkazy
- Co je to vlastně "uživatel"?
- Vlastnictví objektů
- Přístupová práva
- Vlastník, skupina, ostatní...
- Jak je to se skupinami?
- Skupiny a uživatelé
- Scripty
- Komentáře, a volba shellu
- Pro skript může být shell cokoli!
- Shellové skripty a argumenty
- Skripty a proměnné: aritmetika
- Proměnné shellu, "dědění" hodnot
- Práce s proměnnými
- Práce se jmény souborů
- Pole hodnot
- Další triky kolem polí...
- Standardní proměnné shellu
- Základní příkazy pro skripty
- Příkaz if
- Speciální podmínkové příkazy
- Podmínky pro práci se soubory
- Jednoduchý cyklus
- Příkaz for a pomocné příkazy break a continue
- Příkaz case
- Příkazy exit a select
- Rejstřík a přehled
- Procesy
- Informace o procesech
- Další klíčová slova pro příkaz ps
- Příkaz ps: několik praktických přepínačů
- A k čemu že je "ps" dobré?
- Copak procesor, s pamětí je to horší
- Virtuální paměť
- A ještě jednou virtuální paměť
- Zpět k příkazu ps
- Skutečný žrout paměti
- Ještě jednou top
- Doplněk k topu: vm_stat
- Co to tedy všechno znamená?
- Nevychází nám dal a má dáti?
- Kam se stránky ukládají?
- Změna odkládacího disku
- Změna odkládacího disku / fstab
- Poslední poznámka k fstab
- A jak to je se soubory?
- Co vlastně příkaz lsof vypisuje?
- Příkaz lsof a obsah sloupce NAME
- SIPS - Terminál není jen pro nadšence UNIXu
- Tak nám zabili NetInfo, paní Müllerová