Reklama

zonerbooks.cz | zoner.cz | czechia.com | regzone.cz | inshop.cz | inmail.cz | zonerpress.cz | zonerantivirus.com | zonerama.cz

interval.cz

Využití regulárních výrazů v JavaScriptu

03. 02. 2010 | Pavel Salvet | JavaScript a Ajax | Komentáře: 9

Bez regulárních výrazů se dnes programátoři neobejdou a je dobré seznámit se s jejich možnostmi i v JavaScriptu. Článek obsahuje test vašich znalostí.

Příklady uvedené ve článku byly 16. 3. 2012 aktualizovány.

V JavaScriptu se regulární výraz dá vytvořit dvěma způsoby:

var re1 = /Regular Expression/i;
var re2 = new RegExp("Regular Expression","i");

První způsob je jednodušší, ale neumožňuje uvnitř RE použít proměnnou. Vyhodnocování RE lze ovlivnit připojením modifikátorů. Např. modifikátor i způsobí, že se nebudou rozlišovat malá a velká písmena.

Testování výskytu

Ke zjištění, zda se v určitém řetězci nachází podřetězec odpovídající danému RE, ideálně poslouží metoda test() objektu RegExp. Jejím argumentem je testovaný řetězec. Vrací hodnotu typu boolean. První příklad, tělo návratové funkce volané při pokusu o odeslání formuláře, slouží ke kontrole správného tvaru e-mailové adresy.

var str = document.forms[0].elements[0].value; // vložená hodnota předpokládaného elementu input
var vzor = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]){2,3}$/;
var isEmail = vzor.test(str);
return isEmail;

Hledání pozice výskytu

Metoda search() objektu String zjišťuje, kde v řetězci se nalézá podřetězec odpovídající danému RE, kterýžto má za argument. Vrací index pozice prvního výskytu hledaného podřetězce. Jestliže ten nalezen není, vrací -1. Jedná se tedy o obdobu metody indexOf(). V následujícím příkladu je použita pro bližší určení místa pravopisné chyby.

var veta = "Zlodějky b_l_ chyceny, když kradl_ obraz_.";
var znamka = null;
var pozice_chyby, hlaska;
do {
  veta = window.prompt("Doplňte: ", veta);
  if (veta == "Zlodějky byly chyceny, když kradly obrazy.") {
    znamka = 1;
    hlaska = "Výborně";
    }
  else {
    pozice_chyby = veta.search(/[i_]/); //!!!
    hlaska = (pozice_chyby > -1)? "Chyba u " + ++pozice_chyby + ". znaku" : "Špatně";
    }
  window.alert(hlaska);
}
while (!znamka);

Náhrady a ošetření uživatelského vstupu

Má-li být jako součást RE použit uživatelský vstup, je nutné pamatovat na to, že by mohl obsahovat speciální znaky (+, ?, [, \, . aj.), a tuto eventualitu ošetřit, aby sestavený RE byl korektní a fungoval zamýšleným způsobem! Řešení je jednoduché: před každý případný speciální znak z uživatelského vstupu se vsune obrácené lomítko (\), tím inkriminovaný znak pozbude svého zvláštního významu. Splnění tohoto úkolu dokonale zajistí metoda replace() objektu String, které se předávají dva argumenty - tím prvním je RE, tím druhým náhradní podřetězec. Vrací změněný řetězec. Celé to vypadá takhle:

var str = document.forms[0].elements[0].value; // vložená hodnota předpokládaného elementu input
str = str.replace(/(["\\\|\[\]\^\*\+\?\.\$\(\)\{\}])/g, "\\$1"); // ošetření daného uživatelského vstupu
var re = new RegExp(str,"i");

Poznámka k příkladu: výraz $1 uvedený v druhém argumentu reprezentuje shodu s tou částí RE, která je uzavřena v kulatých závorkách.

Získání podřetězce

Jak extrahovat z řetězce nějakou jeho specifickou část? Způsobů je více, ale nejsnadněji se to obvykle zvládne prostřednictvím metody exec() objektu RegExp nebo metody match() objektu String. Není-li nalezen kýžený podřetězec, vracejí null, jinak vracejí pole, jehož prvním prvkem je podřetězec odpovídající celému RE a případnými dalšími prvky jsou podřetězce shodné s jednotlivými podvýrazy (podvýrazy jsou v RE vyznačeny kulatými závorkami).

Zvlšť efektivního uplatnění dosáhnou tyto metody v případech, kdy je cílem získat jenom určitou součást hledaného podřetězce, například jen číselnou hodnotu z ceny zboží. Provedou totiž de facto dva úkoly najednou. V daném příkladě za prvé: naleznou cenovou položku, za druhé: oddělí číslo od měny.

var product = sessionStorage.cenovaBomba;
var price = product.match(/(\d+),- Kč/);
alert("Kupte to teď. Příště to bude stát "+price[1]*1.5+",- Kč!");

Rozdělení řetězce

Metoda split() objektu String vytvoří pole řetězců z řetězce, který rozdělí. Jako oddělovač slouží RE, předaný metodě formou argumentu. Oddělovače nejsou do prvků pole zahrnuty, slouží jenom pro rozpoznání konce a začátku jednotlivých položek. Opět jeden malý příklad:

var vyzva = window.prompt("Jaké jsou tvé oblíbené sporty");
var sporty = (vyzva)? vyzva.split(/,\s?/) : "";
var pocet = sporty.length;
while (pocet--) {
  navrh = window.confirm("Zahraješ si se mnou "+sporty[pocet]+"?");
  if (navrh) break;
}

Test na regulární výrazy

Programátorům webových aplikací jsou regulární výrazy užitečné zejména při validaci (ověřování formální správnosti) vstupních dat, neboť umožňují výrazně snížit množství přijatých údajů nevhodného tvaru. Jde s nimi například zjistit, jestli hodnota zadaná do textového pole začíná alespoň třemi písmeny a podobné věci. O tom, jak vypadají, už bylo napsáno dost, bohužel fakt je ten, že se dají naučit jen praxí. K praktickému pochopení regulárních výrazů snad přispěje i slíbený testík.


Reklama


Další aktuální články na interval.cz

Tematicky související články

Dejte vědět i ostatním o článku

Komentáře ke článku

Přidat nový komentář

Shark

Autor komentáře: Shark

Datum vložení: 03. Únor 2010, 09:37:48

Příklad 7 obsahuje chybu.

Miroslav Kučera

Autor komentáře: Miroslav Kučera

Datum vložení: 03. Únor 2010, 14:10:29

Shark -> myslite jako priklad 7 v testu?

Shark

Autor komentáře: Shark

Datum vložení: 04. Únor 2010, 08:47:51

Ano, přesně tak. Zadanému výrazu neodpovídá žádné z nabízených řešení. Předpokládám, že výraz měl být (999){3}, popřípadě chyták 999{3,}.

Lubor Bílek

Autor komentáře: Lubor Bílek

Datum vložení: 05. Únor 2010, 08:41:53

Shark -> Proč si myslíte, že řetězec "999999999" nevyhoví RE "999{3}"? Já myslím, že je to v pořádku.

Pavel Salvet

Autor komentáře: Pavel Salvet

Datum vložení: 05. Únor 2010, 09:11:52

V příkladu 7 se hledá podřetězec (sic!) složený z pěti devítek. Jedna z možností obsahuje pět (a více) devítek.
Aby byl příklad opravdu špatně, muselo by se na začátek RE přidat ^ a na konec $, pak by se teprve hledala (a nenalezla) shoda s celým řetězcem.

tiso

Autor komentáře: tiso

Datum vložení: 05. Únor 2010, 11:34:48

Príklad 9 je zle napísaný:

[4-91]
23
terminál 1

miesto:
[4-91]

23
terminál 1

tiso

Autor komentáře: tiso

Datum vložení: 05. Únor 2010, 11:35:41

tak inak: [li][ol][4-91]
miesto: [li][4-91][ol]

Lubor Bílek

Autor komentáře: Lubor Bílek

Datum vložení: 05. Únor 2010, 12:18:03

Pavel Salvet: Přesně tak to je. Shark vymyslel "chyták", ale sám se do jednoho nechal chytit ;-)

Shark

Autor komentáře: Shark

Datum vložení: 06. Únor 2010, 10:08:11

Sakra, máte pravdu. Ani nevím proč jsem měl najednou u příkladu 7 pocit, že výrazu musí odpovídat celý řetězec.

Zpět na začátek komentářů | Zpět na začátek článku

Přidat nový komentář

Jméno a e-mail jsou nepovinné. Příspěvky obsahující odkaz jsou moderovány.

Zoner AntiVirus Free pro Android
zabezpečte si svůj smartphone, zdarma
Profesionální eshop Zoner inShop od 990 Kč.
Reklama
Reklama

Syndikace

hledáme nové autory | redakce interval.cz | reklama na interval.cz

© ZONER software, a.s., všechna práva vyhrazena, interval.cz dodržuje právní předpisy o ochraně osobních údajů. Powered by WordPress.