Regulární výrazy a JavaScript – ukázková aplikace
V předešlých článcích jsme si předvedli použití různých metod pro práci s regulárními výrazy v JavaScriptu. Proč si tedy nevytvořit malou webovou aplikaci?
Tato aplikace bude (skoro) všechny tyto metody (nevyužijeme pouze nejjednodušší dvě metody search()
a test()
) používat při práci s řetězci a regulárními výrazy…
Co bude naše aplikace umět?
- najít části vstupního řetězce, které odpovídají regulárnímu výrazu a vypsat je jako seznam oddělený libovolným oddělovačem (použijeme
match()
) - najít části vstupního řetězce, které odpovídají regulárnímu výrazu, zaměnit je za náhradu (s možností použití zpětné reference) a vrátit řetězec po provedení všech náhrad (použijeme
replace()
) - rozdělit vstupní řetězce s použitím oddělovače popsaného pomocí regulárního výrazu a takto získané části spojit pomocí libovolného oddělovače do výstupního řetězce (použijeme
split()
) - najít části vstupního řetězce, které odpovídají regulárnímu výrazu (a jeho subvýrazům), a vypsat je jako číslovaný seznam shod (formát připomínající dvourozměrné pole) (použijeme
exec()
)
Vyzkoušejte si nejdříve hotovou aplikaci (zdrojový kód). Jak vidíte, aplikace obsahuje šest textových vstupních polí (regvyraz
, modifikatory
, oddelovac
, nahrada
, vstup
, vystup
). Ne všechna pole musí být vždy vyplněna – vždy záleží jakou akci (Match, Replace, Split, Exec) budeme chtít provádět. Podívejme se na jednotlivá pole:
- Pole
vstup
obsahuje vstupní text (text, který chceme zpracovat). - Pole
vystup
obsahuje text, který příslušná funkce vrátí. - Pole
regvyraz
obsahuje regulární výraz zapsaný bez oddělovačů (/
) a modifikátorů. - Pole
modifikatory
obsahuje řetězec složený z písmen patřičných modifikátorů (napříkladg
,gi
a podobně). - Pole
oddelovac
je použito pouze při akci Match nebo Split a obsahuje oddělovač (respektive spojovací řetězec) jednotlivých částí. - Pole
nahrada
je použito jen při akci Replace a obsahuje řetězec, který se použije jako náhrada řetězce odpovídajícího regulárnímu výrazu.
Analýza aplikace
Celá aplikace pracuje na velmi jednoduchém principu. Každé z tlačítek (akcí) spustí jednu ze čtyř uživatelsky definovaných funkcí (f_match()
, f_replace()
, f_split()
, f_exec()
). Každá funkce načte z polí formuláře vstupy, které použije jako argument příslušné funkce (metody) postavené na regulárních výrazech (match()
, replace()
, split()
, exec()
). U metod, které vrací pole (match()
, split()
, exec()
), je návratová hodnota převedena na řetězec pomocí funkce join()
(u akcí Match a Split) nebo pomocí procházení pole v cyklu a „ručního“ zřetězení prvků pole (u akce Exec).
Zdrojový kód stránky s formulářem bude vypadat následovně:
<html>
<head>
<meta http-equiv=“Content-Type“ content=“text/html; charset=windows-1250″/>
<meta http-equiv=“Content-language“ content=“cs“/>
<link rel=“stylesheet“ type=“text/css“ href=“reapp.css“/>
<title>Javascript RegExp All-in-1 Tool</title>
<script type=“text/javascript“>
…
zde budou jednotlivé funkce (zdrojový kód viz níže)
…
</script>
</head>
<body>
<h1>Javascript RegExp All-in-1 Tool</h1>
<form id=“reapp“ name=“reapp“ action=““ onsubmit=“return false;“>
<table>
<tr>
<td class=“popis“>Regulární výraz</td>
<td><input class=“txtinput“ type=“text“ name=“regvyraz“ /></td>
</tr>
<tr>
<td class=“popis“>Modifikátory</td>
<td><input class=“txtinput“ type=“text“ name=“modifikatory“ /></td>
</tr>
<tr>
<td class=“popis“>Oddělovač</td>
<td><input class=“txtinput“ type=“text“ name=“oddelovac“ /></td>
</tr>
<tr>
<td class=“popis“>Náhrada</td>
<td><input class=“txtinput“ type=“text“ name=“nahrada“ /></td>
</tr>
<tr>
<td class=“popis“>Vstup</td>
<td><textarea name=“vstup“ cols=“60″ rows=“20″>
</textarea></td>
</tr>
<tr>
<td class=“popis“>Výstup</td>
<td><textarea name=“vystup“ cols=“60″ rows=“20″>
</textarea></td>
</tr>
<tr>
<td class=“popis“>Akce</td>
<td>
<input value=“Match“ type=“submit“ onclick=“f_match()“ />
<input value=“Replace“ type=“submit“ onclick=“f_replace()“ />
<input value=“Split“ type=“submit“ onclick=“f_split()“ />
<input value=“Exec“ type=“submit“ onclick=“f_exec()“ />
</td>
</tr>
</table>
</form>
</body>
</html>
Ve výše uvedeném kódu jsou u některých elementů uvedeny CSS třídy odpovídající externí definici stylů, stylování stránky se však v tomto článku věnovat nebudeme. Výše uvedený zdrojový kód stránky neobsahuje vlastní javascriptové funkce – na ty se podíváme samostatně níže. V kódu stojí za pozornost ještě zápis <form id="reapp" name="reapp" action="" onsubmit="return false;">
, respektive především akce onsubmit="return false;"
, která zajistí, že kliknutí na tlačítka Match, Replace, Split či Exec (což jsou input
prvky typu submit
) nezpůsobí odeslání formuláře.
Funkce f_match()
function f_match()
{
var vstup1=document.reapp.vstup.value;
var regvyraz1=new RegExp(document.reapp.regvyraz.value,document.reapp.modifikatory.value);
var result=vstup1.match(regvyraz1);
document.reapp.vystup.value=result.join(document.reapp.oddelovac.value);
};
Funkce f_match()
je jednoduchá a snad by ani žádný komentář nevyžadovala. Přesto, pár slov se na tomto místě sluší. Vstupní text (řetězec, načtený z formuláře) si uložíme do proměnné vstup1
, poté vytvoříme instanci objektu RegExp
– regvyraz1
. Takto vzniklé proměnné použijeme pro metodu match()
. Pole result
, které metoda match()
vrátí, převedeme pomocí metody join()
na řetězec, který zobrazíme v prvku textarea
.
Funkce f_replace()
function f_replace()
{
var vstup1=document.reapp.vstup.value;
var regvyraz1=new RegExp(document.reapp.regvyraz.value,document.reapp.modifikatory.value);
var result=vstup1.replace(regvyraz1,document.reapp.nahrada.value);
document.reapp.vystup.value=result;
};
Funkce f_replace()
je velmi podobná. Dokonce je ještě jednodušší, protože metoda replace()
vrátí přímo řetězec, který se zobrazí v textarea
.
Funkce f_split()
function f_split()
{
var vstup1=document.reapp.vstup.value;
var regvyraz1=new RegExp(document.reapp.regvyraz.value,document.reapp.modifikatory.value);
var result=vstup1.split(regvyraz1);
document.reapp.vystup.value=result.join(document.reapp.oddelovac.value);
};
Funkce f_split()
má analogickou strukturu jako f_replace()
. Jediný (ale podstatný) rozdíl je v tom, že regulární výraz popisuje řetězec, pomocí nějž se má vstupní text (řetězec) rozdělit na části. Takto vzniklé části (pole řetězců) se opět převedou s použitím metody join()
na výstupní řetězec.
Funkce f_exec()
function f_exec()
{
var vstup1=document.reapp.vstup.value;
var regvyraz1=new RegExp(document.reapp.regvyraz.value,document.reapp.modifikatory.value);
var i=0; //inicializace – počet nalezených shod
var subvyrazy=““; //řetězec pro zapamatování výstupu
while(result1=regvyraz1.exec(vstup1))
{
for(var j=0;result1[j];j++)
subvyrazy=subvyrazy+“[„+i+“][„+j+“]: „+result1[j]+“\n“;
if(!regvyraz1.global) break; //opatření proti zacyklení
i++; //inkrementace – počet nalezených shod
};
document.reapp.vystup.value=subvyrazy;
};
Kód funkce f_exec()
je velmi podobný kódu příkladu (u metody exec()
) v předcházejícím článku. Tato funkce je přeci jen o něco složitější než tři předcházející, proto doporučuji si nejdříve vyzkoušet při jakých vstupech (regulární výraz, modifikátory, vstupní text) vrací jaký výstup (respektive především jak je výstup formátován).
Funkce je postavena na dvou vnořených cyklech. Vnější while
cyklus slouží k opakovanému volání metody exec()
při globálním prohledávání (počet průchodů cyklem zaznamenává počítadlo i
). Vnořený cyklus for
slouží k procházení shod s jednotlivými subvýrazy, tedy de facto pro procházení pole, které vrátí metoda exec()
(počet průchodů tímto cyklem zaznamenává počítadlo j
). V cyklu while
voláme opakovaně result1=regvyraz1.exec(vstup1)
. Navrácené pole result1
procházíme ve for
cyklu a do řetězcové proměnné subvyrazy
vždy zapíšeme (respektive připíšeme) shodu ve tvaru [i][j]: shoda
, kde i udává o kolikátou shodu (při globálním vyhledávání) se jedná (indexováno od nuly!) a j udává, o shodu s kolikátým subvýrazem se jedná (shoda s celým regulárním výrazem je pod indexem 0
).
Určitá komplikace nastává v případě, že nepoužijeme modifikátor g
(globální vyhledávání). V takovém případě je vždy vyhledáváno od začátku řetězce. Podmínka while
je tedy splněna vždy, pokud je v řetězci alespoň jedna shoda. Cyklus se tak stane nekonečnou smyčkou. V našem jednoduchém kódu si dovolím pro řešení použít programátorsky ne zcela nejčistší řešení, a to opuštění while
cyklu pomocí break
na základě otestování vlastnosti global
regulárního výrazu. Zápis if(!regvyraz1.global) break;
tedy říká: Pokud regulární výraz neobsahuje modifikátor pro globální vyhledávání, opusť cyklus.
Souhrn
Nastíněné řešení je pouze jádrem uživatelsky komfortní aplikace. Není však již velkým problémem například místo textového vstupního pole pro regulární výraz použít rozbalovací menu s přednastavenými regulárními výrazy a podobně, a tak zpřístupnit funkčnost i uživatelům, kteří se tolik s regulárními výrazy nekamarádí.
Mohlo by vás také zajímat
-
AI a internetové podvody
29. října 2024 -
Užitečné nástroje pro bezpečnost na internetu
17. října 2024
Nejnovější
-
Výkonný a kompaktní: ASOME Max Studio s výjimečným poměrem cena/výkon
11. listopadu 2024 -
Šokující data od Microsoftu: Kyberútoky rostou o stovky procent!
8. listopadu 2024 -
Chcete jedinečnou doménu? Objevte koncovky FOOD, MEME a MUSIC!
7. listopadu 2024 -
OpenAI představilo novou funkci ChatGPT Search
6. listopadu 2024