Regulární výrazy
Regulární výrazy
Regulární výrazy (regExp = regular expression) slouží jako vzor pro popis textového řetězce. Používají se především pro vyhledávání textů, nebo souborů se jmény odpovídající regulárním výrazům.
Existuje mnoho implementací regulárních výrazů. Všechny jsou si dost podobné, ale také se v mnohém liší. Proto je vždy potřeba projít si dokumentaci programu, který využívá nějakým způsobem regulární výrazy, co všechno umí, co a jak program implementoval. Popis regulárních výrazů v této kapitole je jen stručný úvod do toho, co regulární výrazy umí.
Jednoduché regulární výrazy používá například program ls
.
Hvězdička (*) se interpretuje jako libovolný text, otazník jako
právě jeden libovolný znak.
$ ls ?.txt # všechny soubory s jednopísmenným jménem a koncovkou .txt
Regulární výrazy programu ls
není úplně typický představitel
regulárních výrazů. Normálně hvězdička znamená libovolný počet opakování
znaku nebo části výrazu před hvězdičkou a otazník jedeno nebo žádné opakování
znaku či části výrazu.
Regulární výrazy si nejlépe vyzkoušíte s programem egrep
,
který bude popsán v následující kapitole. Pokud se programu egrep
předá jen regulární
výraz, očekává vstup z klávesnice a každou zadanou řádku, která odpovídá vzoru, vytiskne znovu na
obrazovku.
test
test.txt
test.txt
testtxt
.txt
.txt
Vstup se ukončí klávesovou zkratkou CTRL+d.
Můžete taky použít programy, které jsem vytvořil v článku o programování v C, Regulární výrazy.
Omezovače
Omezovac je znak, ktery oznacuje zacatek a konec regularniho vyrazu. Jako omezovac muzeme pouzit libovolny znak s tim, ze stejny znak pouzijeme na zacatku a konci regularniho vyrazu. Pro jednoduchost zde budu pouzivat jako omezovac lomitko /. V nekterych pripadech, kdy nemuze dojit k nejasnosti, neni treba pouzit druhy, ukoncovaci omezovac.
/*.txt/
Ne všechny programy vyžadují, aby regulární výrazy byli uvnitř mezovačů.
Například program egrep
, nebo programy z mého článku o programování v C, omezovače nepoužívají.
Uvést je je vlastně chybou. Nicméně, v následujících příkladech je budu používat.
Jednoduché řetězce
Jedná se o řetězce, které neobsahují žádné speciální znaky (metaznaky).
- /ring/
- Odpovídá řetězci, který v sobě obsahuje text ring.
Takže ring, ringo, i boring odpovídají.
S programy z mé kapitoly o programování v c, Regulární výrazy, si to můžete
vyzkoušet takto: ./posix -p "ring" "boring"
.
Speciální znaky
. (tečka)
Tečka reprezentuje libovolny znak
/.ak/
reprezentuje vsechny retezce, kde po jednom znaku nasleduje ak
,
například jak, tak.
[] Hranaté závorky
- [znaky]
- reprezentuje jeden z uvedenych znaku v []
- [^znaky]
- reprezentuje znaky, ktere nejsou v [] (nektere implementace misto ^ pouzivaji !)
- [znak1-znak2]
- znaky mezi znak1 a znak2 dle ASCII kodu. (znak1 < znak2),
napriklad [0-9] reprezentuje jedno libovolne cislo.
Metaznaky\
,*
a$
ztraceji uvnitr[]
svuj vyznam. Ma-li byt zavorka]
prvkem tridy znaku, musi byt uvedena ihned po leve hranate zavorce.
Znak^
ma specialni vyznam pouze je-li uveden ihned po leve hranate zavorce.
EXAMPLES
- /[bB]il/
- Odpovídá Bil a bil
- /t[aeiou].k/
- teak, tank, tiik, …
- /[^a-zA-Z]/
- reprezentuje libovolny znak, ktery neni pismeno
* Hvězdička
Hvězdička reprezentuje nula nebo vice vyskytu predchoziho znaku v regularnim vyrazu, nebo vyrazu uzavřeného v závorce.
EXAMPLES
- /.*/
- Hvezdicka, pred kterou je tecka, reprezentuje libovolny retezec znaku (vzcetne prazdneho retezce).
- /ab*c/
- ac,abc,abbc,abbbc, …
- /ab.*c/
- abc, abxc,ab45c, aba;sdfjas;dflja;sdfjc, …
- /[a-zA-Z -]*/
- libovolny retezec slozeny pouze z pismen, mezer a pomlcek.
+ Plus
Plus reprezentuje alespoň jeden výskyt znaku. Je to skoro totéž jako hvězdička, jen neodpovídá prázdnému řetězci (vyžaduje alespoň jeden výskyt).
? Otazník
Otazník reprezentuje nula nebo jeden výskyt předchozího znaku v regulárním výrazu, nebo výrazu uzavřeného v závorce
EXAMPLES
- /.?/
- Reprezentuje žádný, nebo jeden libovolný znak
- /[a-z]?/
- Reprezentuje žádný, nebo jeden malý znak z anglické abecedy
{} Špičaté závorky
Špičaté závorky se používají k určení počtu opakování
- {n}
- Předcházející výraz se opakuje přesně n-krát.
- {n,}
- Předcházející výraz se opakuje nejméně n-krát.
- {n,m}
- Předcházející výraz se opakuje alespoň n-krát, nejvíce však m-krát.
^ Stříška a $ dolar
- ^
- reprezentuje zacatek radky
- $
- reprezentuje koncec radky
EXAMPLES
- /^T/
- reprezentuje retezec, ktery zacina znakem T
- /:$/
- reprezentuje retezec, ktery konci dvojteckou
- /^[a-z]*$/
- reprezentuje retezec, ktery od zacatku radky az do konce obsahuje jen mala pismena anglicke abecedy
\ Zpětné lomítko
Zpětné lomítko ruší speciální význam znaků. Dvě zpětná lomítka zasebou znamenají zpětné lomítko (první lomítko ruší speciální význam následujícího lomítka
EXAMPLES
- /\[5\]/
- reprezentuje retezec obsahující [5], např. pole[5]
- /a\/nebo/
- reprezentuje a/nebo
| Nebo
Znak |
se používá pro výběr z dvou nebo více možností.
EXAMPLES
- /(a|b|xxx)/
- Znak a nebo b nebo text xxx.
Hladovost
Regularni vyraz reprezentuje vzdy nejdelsi mozny retezec. Mame vetu:
Jak jsem jiz drive uvedli (viz kap.4), problem lze resit ruznymi metodami
(prvni reseni podal v roce ...).
Pak vyraz /(.*)/
reprezentuje:
(viz kap.4), problem lze resit ruznymi metodami (prvni reseni podal v roce ...)
Nikoliv jen
(viz kap.4)
.
Výraz /([^)]*)/
reprezentuje (viz kap.4)
, protože [^)]*
odpovídá libovolnému znaku, ale mimo pravé závorky.
() závorky
Závorky v regulárních výrazech združují části regulárního výrazu, se kterými se pak dá zacházet jako s jedním znakem. Regularni vyraz v zavorkach se vetsinou pouziva pri nahrazovani retezcu (viz dale), nebo ve spojeni s urcenim opakovani vyrazu (pomoci hvezdicky, plus, otazniku atd.)
Nahrazování řetězců
Editor vim
a davkovy editor sed
pouzivaji regularni vyrazy pri hledani retezcu v
prikazu nahrazeni (substitute). V tomto pripade lze pouzit dva specialni
znaky ampersand (&) a cislici oznacenou zpetnym lomitkem (\n) pro reprezentaci
retezce uvnitr nahrazujiciho retezce.
- & (ampersand)
- uvnitr nahrazujiciho retezce reprezentuje cely nalezeny retezec.
- \n
- n je lomitkem oznacena cislice, ktera uvnitr regularniho vyrazu reprezentuje hodnotu retezce regularniho vyrazu uzavreneho v n-te zavorce.
EXAMPLES
Priklad v programu sed
. Chceme kolem vsech cisel doplnit znaky NN:
s/[0-9][0-9]*/NN&NN/
s
je příkaz pro sed
, že se má reg. výraz nahrazovat.
Mezi prvními lomítky / je regulární výraz, který se hledá, mezi druhým a třetím lomítkem
je výraz, kterým se má nahrazovat.
Priklad v editoru vim: mame soubor obsahujici radky formatu: prijmeni, jmeno
.
Format chceme zmenit na jmeno prijmeni
:
%s/\([^,]*\), \(.*\)/\2 \1/
%s
znamená nahrazování v celém souboru.
Prikaz nahrazeni ve hledanem
retezci pouziva dva regularni vyrazy v zavorkach. Prvni vyraz v zavorkach
reprezentuje retezec, ktery neobsahuje carku (prijmeni). Za timto vyrazem
nasleduje carka a mezera a dale nasleduje druhy regularni vyraz v zavorkach.
Tento vyraz reprezentuje libovolny retezec (jmeno).
Nahrazujici retezec je tvoren tim, co reprezentuje regularni vyraz v
druhých zavorkach (\2), mezerou a regularnim vyrazem v prvnich zavorkach (\1).
Featury
Zde popisované featury nejsou součástí definice regulárních výrazů, ale některé programy jej implementují.
Prazdny regularni vyraz reprezentuje posledni pouzity regularni vyraz.
Pokud v textovem editoru vim
pouzijeme prikaz
s/Petr/Robert/
a pote chceme tuto substituci zopakovat,
muzeme pouzit prikaz s//Robert/
.
Prazdny regularni vyraz (//) reprezentuje vyraz Petr.