Regulární výrazy a JavaScript – metody search() a replace()
V předchozím článku jsme si stručně zopakovali obecné konstrukce regulárních výrazů a tak se nyní můžeme směle pustit do postupů a metod používajících regulární výrazy přímo v JavaScriptu.
Pro regulární výrazy existuje v JavaScriptu zvláštní objektový typ RegExp
. Existují v zásadě dvě možnosti práce s regulárními výrazy:
- Použití metod objektu
String
, kterým jako argument předáme regulární výraz, jehož shodu s řetězcem (String
) chceme testovat. - Použití metod objektu
RegExp
, kterým jako argument předáme řetězec, jehož shodu s regulárním výrazem chceme testovat.
Regulární výraz můžeme vytvořit dvěma způsoby:
- jako literál:
var re=/regexp/
nebovar re=/regexp/modifikátory
- pomocí konstruktoru objektu:
var re=new RegExp("regexp")
nebovar re=new RegExp("regexp","modifikátory")
V obou případech regexp představuje příslušný regulární výraz a modifikátory představuje nepovinně zadané modifikátory. (V kontextu JavaScriptu se v anglicky psaných materiálech setkáme s označením „flag“, což by se spíše mělo překládat jako „příznak“, ale pro zachování konzistence s texty o regulárních výrazech v PHP budu i zde používat označení „modifikátor“.)
V případě zápisu regulárního výrazu coby literálu je tento z obou stran uzavřen takzvanými oddělovači. V JavaScriptu jsou jediným povoleným oddělovačem lomítka (/
). V případě vytváření regulárního výrazu pomocí konstruktoru objektu RegExp
nesmíme zapomenout všechny výskyty zpětného lomítka doplnit ještě o jedno zpětné lomítko. Chceme-li tak vytvořit například regulární výraz, kterému odpovídá sekvence čtyř číslic, musíme použít zápis var re=new RegExp("\\d{4}")
.
Přečetli jste si předcházející odstavce a stále čekáte na vysvětlení oněch „modifikátorů“? Modifikátory jsou příznaky, které určitým způsobem ovlivňují vyhodnocování regulárního výrazu. V JavaScriptu existují tři modifikátory:
i
(ignore case) – způsobí nerozlišování malých a velkých písmen při porovnávání řetězce s regulárním výrazem; regulárnímu výrazu/ahoj/i
tak budou odpovídat řetězceahoj
,Ahoj
iaHoJ
a dalšíg
(global search) – způsobí, že i když ve vstupním řetězci bude již nalezen jeden podřetězec odpovídající regulárnímu výrazu, hledání shody bude pokračovat dále ve zbytku řetězce; máme-li například text těla e-mailu obsahující mnoho e-mailových adres a chceme vyhledat či extrahovat všechny tyto adresy, pak použijeme právě modifikátorg
)m
(multiple lines) – způsobí, že dojde ke shodě kotvy^
i na začátku každého řádku a ke shodě kotvy$
i na konci každého řádku (standardně dochází ke shodě jen na začátku, respektive na konci řetězce)
Všechny modifikátory lze kombinovat, přičemž na jejich pořadí nezáleží. Zápis /ahoj/ig
je tak zcela ekvivalentní zápisu /ahoj/gi
.
Metody objektu String
Pro práci s regulárními výrazy disponuje objekt String
těmito metodami:
search()
– zjistí, zda řetězec či alespoň jeho část odpovídá regulárnímu výrazureplace()
– nahradí řetězec (nebo jeho část) odpovídající regulárnímu výrazu jiným zadaným řetězcemmatch()
– najde a vrátí část nebo části řetězce odpovídající regulárnímu výrazusplit()
– rozdělí řetězec na části; oddělovačem je řetězec odpovídající regulárnímu výrazu
Níže si probereme první dvě ze zde uváděných metod. Metodám match()
a split()
věnujeme samostatný článek.
search()
Zapisujeme ve tvaru řetězec.search(regexp)
, kde řetězec je text, který testujeme na shodu s regulárním výrazem regexp.
Funkce vrací pozici znaku v řetězci, kde začíná část řetězce, která odpovídá regulárnímu výrazu (takovou část řetězce budeme označovat jako „shoda“). Pokud není žádná shoda nalezena, vrací -1
. Vše bude zřejmé z malého příkladu, který si můžete sami vyzkoušet.
//search() – příklad 1
//přímý zápis
var result0=“Interval“.search(/val/); //vrací: 5
alert(„Nalezeno na pozici: „+result0+“ (přímý zápis)“);
//vytvoření a použití proměnných (RegExp vytvářen jako literál)
var str1=“Interval“;
var re1=/val/;
var result1=str1.search(re1); //vrací: 5
alert(„Nalezeno na pozici: „+result1+“ (s použitím proměnných)“);
//vytvoření a použití proměnných (RegExp vytvářen jako objekt)
var str2=“Interval“;
var re2=new RegExp(„val“);
var result2=str2.search(re2); //vrací: 5
alert(„Nalezeno na pozici: „+result1+“ (s použitím proměnných podruhé)“);
V ukázce jsou demonstrovány tři postupy vedoucí ke stejnému výsledku. V prvním případě nejsou explicitně inicializovány žádné proměnné. V druhém případě je vytvořena řetězcová proměnná a regulární výraz (jako literál). Ve třetím případě je regulární výraz vytvářen pomocí konstruktoru objektu RegExp
.
replace()
Zapisujeme ve tvaru řetězec.replace(regexp, náhrada)
, kde řetězec je text, v němž má být provedeno nahrazení, regexp je regulární výraz popisující část řetězce, která má být nahrazena a náhrada je řetězec, kterým se má odpovídající část řetězce nahradit.
Funkce vrací upravený řetězec. Pokud chceme provést náhradu pro všechny (regulárnímu výrazu) odpovídající podřetězce, musíme použit modifikátor g
. Jako součást náhrady můžeme také použít:
- zpětnou referenci na část řetězce odpovídající regulárnímu výrazu (či subvýrazu)
- část řetězce předcházející řetězci, který vytváří shodu
- část řetězce následující po řetězci, který vytváří shodu
Způsoby, jak zapsat tyto speciální případy uvádí následující tabulka:
$1, …, $99 | text, který odpovídá 1. až 99. regulárnímu subvýrazu |
$& | text, který odpovídá celému regulárnímu výrazu |
$` | text předcházející textu, který vytváří shodu s regulárním výrazem |
$‘ | text následující za textem, který vytváří shodu s regulárním výrazem |
Mimochodem, pokud budete chtít v náhradě zapsat obyčejný znak dolaru v takovém místě, kde by ho bylo možno vykládat jako součást některé z výše uvedených speciálních konstrukcí, zapište dolar zdvojeně ($$
). Například zápis $$1
tak nebude chápán jako reference na první subvýraz, ale jako prostý text „$1“.
//replace() – příklad 1
//jediná náhrada – bez modifikátoru „g“
var str=“15 USD, 10 EUR, 300 CZK“;
var re1=/(\d+)\s(\w+)/;
var result1=str.replace(re1,“$2=$1″); //vrátí: USD=15, 10 EUR, 300 CZK
alert(„Původní text: „+str+“\nZměněný text: „+result1);
//vícenásobná náhrada – s modifikátorem „g“
var str=“15 USD, 10 EUR, 300 CZK“;
var re2=/(\d+)\s(\w+)/g;
var result2=str.replace(re2,“$2=$1″);
//vrátí: USD=15, EUR=10, CZK=300
alert(„Původní text: „+str+“\nZměněný text: „+result2);
Myslím, že příklad ani nepotřebuje komentář. Je zřejmé, že bez použití modifikátoru g
se řetězec následující po první úspěšné shodě (, 10 EUR, 300 CZK
) ignoruje a k žádné záměně zde tak již nedochází.
Protože však regulární výraz /(\d+)\s(\w+)/
(nebo jeho verzi s modifikátorem g
) budeme používat i v dalších příkladech (a jeho plné pochopení je tedy klíčové), připomenu raději jeho princip. Části (\d+)
odpovídá sekvence číslic 0-9 (minimálně jedna číslice). Uzavření \d+
do kulatých závorek značí, že řetězec odpovídající regulárnímu subvýrazu \d+
je zapamatován a může být použit pomocí zpětné reference. Části \s
odpovídá jeden „bílý znak“ (například mezera či tabulátor – úplný výčet viz Regulární výrazy a JavaScript – úvod). Části (\w+)
odpovídá sekvence alfanumerických znaků (včetně znaku podtržítka), přičemž je vyžadován minimálně jeden takový znak. Uzavření \w+
do kulatých závorek značí, že řetězec odpovídající regulárnímu subvýrazu \w+
(v našem případě označení příslušné měny) je zapamatován a může být použit pomocí zpětné reference.
Příklad 2:
//replace() – příklad 2
//náhrada obsahující celý řetězec odpovídající reg. výrazu
var str=“15 USD, 10 EUR, 300 CZK“;
var re3=/(\d+)\s(\w+)/g;
var result3=str.replace(re3,“Cena: $&“);
//vrátí: Cena: 15 USD, Cena: 10 EUR, Cena: 300 CZK
alert(„Původní text: „+str+“\nZměněný text: „+result3);
Jako náhrada je použit text Cena:
následovaný referencí na text odpovídající celému regulárnímu výrazu ($&
). Díky modifikátoru g
se provede záměna třikrát.
//replace() – příklad 3
var str=“abc12345def“;
var re4=/\d+/;
var result4=str.replace(re4,“Před: $` – Za: $‘ – Shoda: $&“);
//vrátí: abcPřed: abc – Za: def – Shoda: 12345def
alert(„Původní text: „+str+“\nZměněný text: „+result4);
Tento příklad demonstruje použití speciálních konstrukcí z výše uvedené tabulky. Regulárnímu výrazu /\d+/
odpovídá v našem příkladu řetězec 12345
. Pouze tento řetězec bude nahrazen „náhradou“. Zbytek řetězce, který neodpovídá regulárnímu výrazu, bude vrácen bez změny (v našem případě sekvence znaků abc
a sekvence znaků def
).
//replace() – příklad 4
//uživatelská funkce
function desetkrat(cena)
{
return 10*cena;
};
var str=“15 USD, 10 EUR, 300 CZK“;
var re5=/\d+/g;
var result5=str.replace(re5,desetkrat);
//vrátí: 150 USD, 100 EUR, 3000 CZK
alert(„Původní text: „+str+“\nZměněný text: „+result5);
Argumentem náhrada nemusí být jen řetězec, ale také název uživatelské funkce, která převezme jako svůj argument řetězec odpovídající regulárnímu výrazu, ten nějakým způsobem zpracuje a výsledek vrátí zpět metodě replace()
(v PHP lze analogické chování docílit pomocí funkce preg_replace callback()
). Volání uživatelské funkce se tedy provede pro každé jednotlivé nahrazení.
Jak vidíme, uživatelská funkce desetkrat()
provádí prostý úkon – vynásobí funkci předanou hodnotu deseti (regulárnímu výrazu /\d+/g
odpovídají pouze čísla obsažená v řetězci str
). Jako náhrada je sice zadán název funkce desetkrat
, avšak jako skutečná náhrada bude použita návratová hodnota této funkce.
Ke stažení
Veškeré zde uvedené příklady si můžete stáhnout a otestovat přímo ve svých prohlížečích, samozřejmě jen v případě, že podporují JavaScript a regulární výrazy.
Starší komentáře ke článku
Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.
Mohlo by vás také zajímat
-
ZONER Webmail jako první v Česku přináší BIMI s VMC
11. července 2024 -
Webdesign: Jak optimalizovat tlačítka na webu
7. března 2024 -
AI na dosah ruky: Jak je to s AI v osobních zařízeních?
22. ledna 2024 -
Proč investovat do nejvýkonnějších VPS s AMD EPYC procesory
14. června 2024
Nejnovější
-
Jak rozšířit úložiště Macu za pětinovou cenu?
16. prosince 2024 -
Nové trendy v doménách pro osobní projekty – DIY, LIVING a LIFESTYLE
9. prosince 2024 -
Jak chránit webové stránky před Web/AI Scrapingem
27. listopadu 2024 -
Jaký monitor je nejlepší k novému Macu Mini?
25. listopadu 2024