Regulární výrazy v JavaScriptu
Regulární výrazy vznikly z důvodu potřeby práce s textovými řetězci určitým unifikovaným způsobem. Samotný výraz je specifickým popisem daného řetězce nebo znaku. Lze je tedy využít pro kontroly, zda řetězec splňuje určitá pravidla (validace) nebo pro vyhledávání v řetězci, kdy neznáme (nebo jednoduše nechceme se tímto způsobem omezovat) přesný obsah podřetězce.
Výrazem je řetězec spojený s určitými tzv. metaznaky a kvalifikátory. Zápis není složitý, avšak je velmi obsáhlý a nepřehledný. Proto si zvykněte výrazy vždy komentovat. Zde máme seznam metaznaků upřesňující "anonymní" znaky:
Tečka
Tečka zastupuje jeden libovolný znak. Například výraz o čtyřech tečkách (....) může být cokoliv o délce 4 a více znaků.
- Abcd = platné
- H@st = platné
- cdf = neplatné
- dfgsd = platné
Ale proč se výraz považuje za platný i po překročení délky? Logicky by neměl projít. Jenže maximální délka výraz vůbec nezajímá. Jakmile projdou čtyři tečky, výraz je platný i se zbytkem. Ale i toto má jednoduché řešení a to použitím hranic neboli ukotvení.
Hranice a ukotvení
Pokud potřebujeme, aby se hledaný řetězec měl určitý začátek i konec (tzn. nezačíná uprostřed slova), použijeme ohraničení neboli ukotvení. Pro začátek zde máme ^, pro konec $. Předchozí výraz bude tedy vypadat takto:
^....$
Nyní výraz označuje textový řetězec přesně o 4 libovolných znacích.
Kvantifikátory (quantifiers)
Kvantifikátory určují kolikrát se smí opakovat zvolený znak (popř. řetězec). Zde jsou jednotlivé typy:
- ? - minimálně 0krát, maximálně 1krát
- * - minimálně 0krát (maximálně neomezeno)
- + - minimálně 1krát (maximálně neomezeno)
- {n} - právě n krát
- {m,n} - minimálně m krát, maximálně n krát
- {m,} - minimálně m krát (maximálně neomezeno)
Zápis kvantifikátorů
Pro použití kvantifikátoru uzavřeme část výrazu do kulatých závorek(), za něž doplníme zvolený kvalifikátor. Zde je alternativa k prvnímu výrazu za pomocí kvantifikátoru:
^.{4}$
Hranaté závorky
Pokud chceme povolit právě jeden z několika znaků (a nebo b nebo c...), uzavřeme takovou skupinu do hranatých závorek [ ]. Pokud naopak určité znaky chceme zamítnout, do hranatých závorek přidáme stříšku(^). Zápis[^ab], tak znamená, že se v daném místě může vyskytovat jakýkoliv znak kromě a nebo b.
Interval
Často potřebujeme vybrat například všechna čísla od 1 do 9 nebo A - Z. Určitě by se vám je nechtělo ručně vypisovat. Naštěstí regulární výrazy podporují intervaly, tzn. 1 až 9. Zápis je stejný jako u ručně vypisovaných skupin, ale přidáme pomlčku(-). [a-z] tedy znamená abcdefgh... Zálaží na velikosti písmen, [A-Z] tedy označuje jen velká písmena, [a-z] jen malá, [a-zA-Z] malá i velká.
Zástupné (zjednodušující) znaky
Pro často používané skupiny znaků existují speciální zkratky (například zápis \d zastupuje všechny číslice 0-9)
Předdefinované skupiny znaků:
- \d - číslice 0-9
- \D - jakýkoliv znak kromě číslic 0-9
- \w - znaky "slova" (a-z, A-Z, 0-9 a podtržítko)
- \W - jakýkoliv znak kromě znaků "slova"
- \s - "bílé" znaky (mezera, tabulátor, znaky pro zalomení řádků)
- \S - jakýkoliv znak kromě "bílých" znaků
Nebo
Pokud chceme vybrat jedno nebo druhé, můžeme použít operátor OR a kulaté závorky (A|B).
Escapování
Občas potřebujeme použít nějaký metaznak jako součást hledaného výrazu. Daný znak tedy musíme odescapovat. Escapování v regexu probíhá stejně, jako normální sekvence escape tzn. Před každý takový znak vložím zpětné lomítko.
Příklady regulárních výrazů
Příklad 1 – emailová adresa
Jako první příklad na procvičení se pokuste vymyslet, jak zvalidovat emailovou adresu. Napovím pouze tím, že bude vhodné použít intervaly a dvakrát kvantifikátor +. Nezapomeňte také, že emailová adresa může obsahovat pouze znaky ._- ,čísla a abecední znaky. Koncovka je dlouhá 2 – 4 znaky a může se skládat pouze ze znaků abecedy.
Řešení:
[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-z]{2,4}
Příklad 2 – telefonní číslo
Představme si, že provozujeme nějakou anketu a potřebujeme zjistit, zda je dané číslo korektní. Může mít jakoukoliv předvolbu, není ničím limitované, pouze musí dohromady obsahovat 12 čísel a jedno +. Pro zjednodušení jsme již předem z čísla odstranili mezery pomocí funkce replace(), takže se jimi nemusíte zabývat.
Řešení:
^\+(\d){3}[0-9]{9}$
Pokud se chcete inspirovat nebo si s nějakým výrazem prostě nevíte rady, podívejte se na tento web regexlib. Součástí je i tester, kde si výraz můžete vyzkoušet.
Třída RegExp
A konečně si ukážeme použití regexu v JavaScriptu. JS obsahuje speciální třídu RegExp, která za nás regulární výrazy vykonává.
Máme k dispozici dva konstruktory:
var regexp = new RegExp(vzor, modifikátory); //Nebo var regexp = /vzor/modifikátory
Výrazy jsme si již vysvětlili, modifikátory jsou už jen takovým malým doplňkem. Zde je seznam:
- i = case-insensitive (nekouká na velikost písmen)
- g = prohledá všechny výrazy namísto zastavení se po jednom
- m = multiline (víceřádkový režim, hranice označují začátek a konec řádku místo začátku a konce celého řetězce)
Regexp.test(string)
Konečně se dostáváme k nejčastějšímu využití regulárních výrazů a to k validaci. Metoda test otestuje, zda daný výraz našel shodu. Vrací true-false. Kontrola emailu v JS by tedy vypadala např. takto:
var re = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-z]{2,4}$/; var platny = re.test("[email protected]"); document.write(platny)
Zkuste si to
String.match(Regexp)
Vrátí pole podřetězců, které odpovídají danému regulárnímu výrazu. Následující kód najde v textu všechna slova, která začínají na itn a poté pokračují alespoň jedním slovním znakem:
var str="Na itnetwork rozvijim sve developerske schopnosti."; var n=str.match(/itn\w+/g); document.write(n);
Vidíte, že využití regulárních výrazů je obrovské, můžeme velmi jednoduše prohledávat řetězce, případně pomocí regulárních výrazů i řetězce nahrazovat. To se dělá metodou replace na stringu.
Tak tímto jsme zakončili povídání o Regexu a zároveň jsme
odhalili většinu tajemství řetězců. Příště si zkusíme něco
zábavnějšího, co třeba browser hru Pong ze starých Atari
za pomoci knihovny JQuery?