TOC

This article has been localized into Czech by the community.

Regulární výrazy:

Vyhledávání/nahrazování s použitím regulárních výrazů

V posledních několika článcích jsme probrali všechny skvělé možnosti pro provádění operací vyhledávání a porovnávání s regulárními výrazy. To samo o sobě může být extrémně užitečné, ale ještě jsme nediskutovali o jedné z nejmocnějších věcí, které můžete s těmito regulárními výrazy dělat: operace vyhledávání a nahrazování. Místo toho, abychom jen našli řetězec uvnitř jiného řetězce, můžeme aktivně nahradit odpovídající řetězec/řetězce jinými řetězci.

replace() and replaceAll()

Pro provádění operací nahrazení na řetězci použijeme buď replace() nebo replaceAll(), což jsou metody nalezené na vestavěném objektu String. Jak jsme již dříve probírali, tyto metody mohou jako argumenty přijímat jednoduchý řetězec pro základní operace vyhledávání a nahrazování, nebo mohou přijímat regulární výraz pro operace vyhledávání a nahrazování založené na regulárních výrazech.

Jak bylo zmíněno dříve, metoda replace() je citlivá na velká a malá písmena při použití jednoduchých řetězců jako argumentů, takže abychom začali používat verzi této metody s regulárními výrazy, dovolte mi ukázat vám, jak ji můžeme udělat necitlivou na velkost písmen s pomocí regulárního výrazu:

let s = "Hello, wOrLd - what a crazy WoRlD indeed!";
let regex = new RegExp("world", "i");

alert(s.replace(regex, "universe"));
// Result: Hello, universe - what a crazy WoRlD indeed!

Všimněte si, jak jsem použil naprosto hloupé velké písmeno v řetězci pro slovo "svět". I tak můžeme tuto instanci nahradit slovem "vesmír". Budeme ignorovat velká písmena, použitím regulárního výrazu s příznakem i (ignorovat velikost písmen).

Také si všimněte, že je nahrazen pouze první výskyt. To je výchozí chování metody replace() - pokud chcete nahradit všechny výskyty, musíte zadat globální příznak g. Poté můžete zavolat metodu replace() nebo replaceAll() - ve skutečnosti to nebude mít velký rozdíl, protože obě metody vyžadují pro nahrazení více než jednoho výskytu specifikovaný globální příznak. Zde je upravený příklad:

let s = "Hello, wOrLd - what a crazy WoRlD indeed!";
let regex = new RegExp("world", "ig");

alert(s.replaceAll(regex, "universe"));
// Result: Hello, universe - what a crazy universe indeed!

Použití skupin zachycení

V předchozím článku jsme viděli sílu používání skupin zachycení v regulárních výrazech při provádění porovnávání řetězců. Mohou být použity také při operacích hledání/nahrazení, což může být v mnoha situacích nesmírně užitečné.

Jako příklad vytvořme malý kus kódu, který bude zvýrazňovat čísla v řetězci. Takže kdykoli narazíme na číslo, nahradíme ho řetězcem obsahujícím číslo obklopené HTML značkami. Zde je ukázka, jak toho lze snadno dosáhnout:

let s = "42 cats, 17 dogs and 11 rabbits";
let regex = new RegExp("([0-9]+)", "ig");

alert(s.replaceAll(regex, "<b>$1</b>"));
// Result: 
// <b>42</b> cats, <b>17</b> dogs and <b>11</b> rabbits

Všimnete si, že v řetězci pro nahrazení používám speciální notaci. Symbol $1 jednoduše udává, že zde chci použít hodnotu první skupiny zachycení. Jelikož jsme v regulárním výrazu specifikovali pouze jednu skupinu zachycení, bude to číslo, které bylo v řetězci nalezeno.

Více skupin zachycení

Dalším velmi běžným příkladem používaným k demonstraci hledání/nahrazení se skupinami zachycení je obrácení jména a příjmení, jako například "John Doe". Většina lidí na západě píše nejprve své křestní jméno a poté příjmení, ale někdy je praktičtější uvádět příjmení na prvním místě, například při výpisu autorů knih atd. Typický formát pro toto je "Doe, John". Můžeme napsat kus kódu využívajícího jednoduchý regulární výraz k dosažení tohoto cíle:

let authors = 
`William Shakespeare
Charles Dickens
Agatha Christie`;

let regex = /^(\w+) (\w+)$/img;
alert(authors.replace(regex, "$2, $1"));
/* Result:
Shakespeare, William
Dickens, Charles
Christie, Agatha
*/ 

Dovolte mi rychle projít tímto příkladem. Nejprve máme řetězec obsahující několik jmen autorů. Poté definujeme regulární výraz, který bude odpovídat dvěma slovům na řádek a umístí je do samostatných skupin zachycení (jak je označeno okolními závorkami). Když provádíme operaci nahrazení, jednoduše specifikujeme, že chceme nejprve hodnotu druhé skupiny zachycení (příjmení), následovanou čárkou a poté křestní jméno (první skupina zachycení).

Výsledkem je seznam jmen, kde byla jména a příjmení obrácena, jak bylo slíbeno.

Můžete si všimnout, že jsem do regulárního výrazu přidal další příznak: Příznak m (multiline) pro víceřádkový režim. Umožňuje nám používat operátory ukotvení regexu k odpovídání na začátku (použitím operátoru ^) a na konci (použitím operátoru $) každého řádku. Opět, toto není tutoriál k regulárním výrazům, takže pro více informací o části týkající se regulárních výrazů se, prosím, poraďte s jiným tutoriálem - chtěl jsem to zatím jen zmínit.

Pojmenované skupiny zachycení

Samozřejmě můžeme použít pojmenované skupiny zachycení i v operacích hledání/nahrazení. Pojďme přepsat předchozí příklad, abychom to ilustrovali:

let authors = 
`William Shakespeare
Charles Dickens
Agatha Christie`;

let regex = /^(?<firstName>\w+) (?<lastName>\w+)$/img;
alert(authors.replace(regex, "$<lastName>, $<firstName>"));
/* Result:
Shakespeare, William
Dickens, Charles
Christie, Agatha
*/ 

Jak vidíte, místo používání číslovaných skupin zachycení ($1, $2 a tak dále) můžeme odkazovat na skupiny zachycení pomocí jmen, která jsme jim dali v regulárním výrazu, obklopených sadou špičatých závorek. To často značně usnadní čtení a porozumění kódu později.

Funkce pro nahrazení

Použití regulárních výrazů pro operace hledání/nahrazení může být velmi mocné, obzvláště když používáte skupiny zachycení, jak můžete vidět z předchozích příkladů. Pro ještě větší flexibilitu však JavaScript nabízí ještě mocnější funkci: schopnost použít funkci pro generování hodnoty pro nahrazení.

Místo určení statického řetězce, jako nahrazení, tedy specifikujete funkci, která bude volána pro každý shodný výsledek. S tím na mysli pojďme zkusit změnit příklad výše, abychom použili tuto techniku k vyřešení malého problému, který jsem právě zavedl: Všechna jména byla zadána někým, kdo byl trochu zmatený ohledně klávesy Shift na klávesnici, což vedlo k několika docela zvláštním problémům s velikostí písmen v seznamu jmen:

let authors = 
`wiLLiam shakeSPEARE
charleS DIckenS
agATha christiE`;

Abych tento problém vyřešil, napsal jsem funkci nazvanou FormalName(), která nejprve opraví problémy s velikostí písmen a poté vrátí části jména v obráceném pořadí, přesně jako jsme to dělali v dřívějších příkladech tohoto článku:

function FormalName(match, firstName, lastName)
{
	firstName = firstName.charAt(0).toUpperCase() + firstName.slice(1).toLowerCase();
	lastName = lastName.charAt(0).toUpperCase() + lastName.slice(1).toLowerCase();
	return lastName + ", " + firstName;
}

let authors = 
`wiLLiam shakeSPEARE
charleS DIckenS
agATha christiE`;

let regex = /^(?<firstName>\w+) (?<lastName>\w+)$/img;
alert(authors.replace(regex, FormalName));
/* Result:
Shakespeare, William
Dickens, Charles
Christie, Agatha
*/ 

Nejprve máme funkci FormalName(). Uvidíte, že v současnosti přijímá tři parametry: shodu, což je jednoduše odpovídající řetězec, a poté dva parametry nazvané firstName a lastName. JavaScript automaticky tyto parametry vyplní při volání funkce, a dokonce můžeme použít skutečná jména skupin zachycení!

Uvnitř funkce FormalName() jednoduše aplikujeme správné psaní na části jména: První písmeno je převedeno na velké, zatímco zbývající znaky jsou převedeny na malá písmena. Poté vrátíme obě části v obráceném pořadí, oddělené čárkou.

Při provádění samotného nahrazení, v posledním řádku příkladu, jednoduše specifikujeme název funkce, která by měla být volána (FormalName) - JavaScript se postará o zbytek za nás. Funkce pro nahrazení může přijímat ještě více parametrů, pokud je potřebujete. Pro úplný seznam se prosím podívejte na specifikaci.

Shrnutí

Provádění operací hledání/nahrazení s pomocí regulárních výrazů je velmi mocný nástroj, který pravděpodobně budete potřebovat. V tomto článku jsme viděli několik příkladů, jak fungují, a jak můžete použít skupiny zachycení a funkce pro nahrazení, abyste tento úžasný nástroj učinili ještě flexibilnějším.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!