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říklad g, 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.

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/ja­vascript“>



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“>Re­gulární
výraz</td>

   <td><input class=„txtinput“
type=„text“ name=„regvyraz“ /></td>

</tr>

<tr>

   <td
class=„popis“>Mo­difikátory</td>

   <td><input class=„txtinput“
type=„text“ name=„modifikatory“ /></td>

</tr>

<tr>

   <td
class=„popis“>Od­dělovač</td>

   <td><input class=„txtinput“
type=„text“ name=„oddelovac“ /></td>

</tr>

<tr>

   <td
class=„popis“>Náh­rada</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ýs­tup</td>

   <td><textarea name=„vystup“
cols=„60“ rows=„20“>

</textarea></td>

</tr>

<tr>

   <td
class=„popis“>Ak­ce</td>

   <td>

      <input value=„Match“
type=„submit“ onclick=„f_match()“ />

      <input value=„Replace“
type=„submit“ onclick=„f_re­place()“ />

      <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=„reap­p“ name=„reap­p“ action="" on­submit=„retur­n false;“>,
respektive především akce
onsubmit=„retur­n 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.

function f_match()

{

var vstup1=documen­t.reapp.vstup­.value;

var regvyraz1=new
RegExp(documen­t.reapp.regvy­raz.value,docu­ment.reapp.mo­difikatory.va­lue);

var result=vstup1­.match(regvyraz1);

document.reap­p.vystup.valu­e=result.join(do­cument.reapp.od­delovac.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
RegExpregvyraz1. 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.

function f_replace()

{

   var vstup1=documen­t.reapp.vstup­.value;

   var regvyraz1=new
RegExp(documen­t.reapp.regvy­raz.value,docu­ment.reapp.mo­difikatory.va­lue);

   var
result=vstup1­.replace(regvy­raz1,document­.reapp.nahrada­.value);

   document.re­app.vystup.va­lue=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.

function f_split()

{

   var vstup1=documen­t.reapp.vstup­.value;

   var regvyraz1=new
RegExp(documen­t.reapp.regvy­raz.value,docu­ment.reapp.mo­difikatory.va­lue);

   var result=vstup1­.split(regvyraz1);

   document.re­app.vystup.va­lue=result.jo­in(document.re­app.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.

function f_exec()

{

   var vstup1=documen­t.reapp.vstup­.value;

   var regvyraz1=new
RegExp(documen­t.reapp.regvy­raz.value,docu­ment.reapp.mo­difikatory.va­lue);

   var i=0; //inicializace – počet nalezených shod

   var subvyrazy=““; //řetězec pro zapamatování
výstupu

   while(resul­t1=regvyraz1.e­xec(vstup1))

   {

      for(var j=0;result1[j];j++)

         subvy­razy=subvyrazy­+„[“+i+„][“+j+„]:
„+result1[j]+“\n“;

      if(!reg­vyraz1.global) break;
//opatření proti zacyklení

      i++; //inkrementace – počet
nalezených shod

   };

   document.re­app.vystup.va­lue=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=regvy­raz1.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.

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í.

Tento článek byl původně publikován na serveru
Interval.cz, kde naleznete originální verzi článku.