TOC

This article has been localized into Czech by the community.

Regulární výrazy (Regex):

Vyhledávání/nahrazování s třídou Regex

Už jsme diskutovali o třídě Regex a o tom, jak ji použít, když chceme prohledávat řetězec v předchozím článku. Regulární výrazy jsou skvělé pro to, ale další případ použití je, když chcete provádět vyhledávací/nahrazovací operace, kde chcete hledat konkrétní vzor a nahradit ho něčím jiným. Třída String již má metodu Replace(), ale ta je dobrá jen pro provádění jednoduchých vyhledávání. Při použití regulárních výrazů můžete využít sílu vyhledávání regulárních výrazů a dokonce použít zachycené skupiny jako součást nahrazovaného řetězce. Zní to složitě? Nebojte se, začneme s jednoduchým příkladem a postupně se budeme přesouvat k pokročilejším případům použití.

Jako v předchozím článku, všechny příklady předpokládají, že jste importovali jmenný prostor RegularExpressions, takto:

using System.Text.RegularExpressions;

S tím na místě se pokusíme pracovat s nahrazováním řetězců založených na regulárních výrazech. Použijeme metodu Replace(), která se nachází na třídě Regex:

string testString = "<b>Hello, <i>world</i></b>";
Regex regex = new Regex("<[^>]+>");
string cleanString = regex.Replace(testString, "");
Console.WriteLine(cleanString);

Tento příklad ukazuje velmi zjednodušený způsob, jak odstranit HTML tagy ze řetězce. Vyhledáme cokoli, co je obklopeno sadou špičatých závorek (<>), a pak použijeme metodu Replace(), aby každý výskyt byl nahrazen prázdným řetězcem, čímž v podstatě odstraníme HTML tagy z testovacího řetězce.

Nahrazení zachycenými hodnotami

Ale řekněme, že je ve skutečnosti nechcete odstranit, ale místo toho je chcete transformovat na něco, co nebude interpretováno prohlížečem, například nahrazením špičatých závorek (<>) hranatými závorkami ([]). Zde Regulární výrazy opravdu ukazují svou sílu, protože je to ve skutečnosti velmi jednoduché, jak je ilustrováno touto mírně přepsanou verzí našeho předchozího příkladu:

string testString = "<b>Hello, <i>world</i></b>";
Regex regex = new Regex("<([^>]+)>");
string cleanString = regex.Replace(testString, "[$1]");
Console.WriteLine(cleanString);

Ve skutečnosti jsem změnil jen dva drobné detaily: Přidal jsem do regulárního výrazu sadu závorek, čímž jsem vytvořil skupinu zachycení, v podstatě zachytil hodnotu mezi špičatými závorkami do první zachycovací skupiny. V metodě Replace() odkazuji na to pomocí speciální notace $1, což v podstatě znamená číslo zachycovací skupiny 1. S tímto nastavením bude náš výstup nyní vypadat takto:

[b]Hello, [i]world[/i][/b]

Pojmenované skupiny zachycení

Samozřejmě můžete udělat přesně to samé, když používáte pojmenované skupiny zachycení (diskutované v předchozím článku), jako v tomto příkladu:

string testString = "<b>Hello, <i>world</i></b>";
Regex regex = new Regex("<(?<tagName>[^>]+)>");
string cleanString = regex.Replace(testString, "[${tagName}]");
Console.WriteLine(cleanString);

Při použití pojmenovaných skupin zachycení použijte notaci ${název-skupiny-zachycení}.

Použití metody MatchEvaluator

Ale co když chceme mít ještě větší kontrolu nad tím, jak je hodnota nahrazena? Můžeme použít parametr MatchEvaluator pro tento účel – jde v podstatě jen o odkaz (delegát) na metodu, která bude volána pokaždé, když má být provedena náhrada, což vám umožňuje upravit nahrazovanou hodnotu, než bude použita. Držme se příkladu s HTML tagy, který jsme již několikrát použili, ale tentokrát si vezmeme kontrolu nad tím, které HTML tagy jsou použity. Zde je kompletní příklad:

using System;
using System.Text.RegularExpressions;

namespace RegexSearchReplaceMethod
{
    class Program
    {
static void Main(string[] args)
{
    string testString = "<b>Hello, <i>world</i></b>";
    Regex regex = new Regex("<(?<tagName>[^>]+)>");
    string cleanString = regex.Replace(testString, ProcessHtmlTag);
    Console.WriteLine(cleanString);
}

private static string ProcessHtmlTag(Match m)
{
    string tagName = m.Groups["tagName"].Value;
    string endTagPrefix = "";
    if(tagName.StartsWith("/"))
    {
endTagPrefix = "/";
tagName = tagName.Substring(1);
    }
    switch (tagName)
    {
case "b":
    tagName = "strong";
    break;
case "i":
    tagName = "em";
    break;
    }
    return "<" + endTagPrefix + tagName.ToLower() + ">";
}
    }
}

První část příkladu vypadá stejně jako předtím, ale místo poskytnutí nahrazovacího řetězce předáváme odkaz na naši metodu ProcessHtmlTag(). Jak bylo zmíněno, tato metoda je volána pokaždé, když má být provedena náhrada, s daným shodným výrazem jako parametrem. To znamená, že v naší metodě MatchEvaluator máme veškeré informace o shodě, takže můžeme jednat odpovídajícím způsobem. V tomto případě využíváme této příležitosti k tomu, abychom tagy udělali více sémantickými tím, že nahradíme tag pro tučné písmo (b) tagem strong a tag pro kurzívu (i) tagem emphasis (em). Ať už je tag změněn či nikoliv, převedeme ho na malá písmena.

Použití parametru MatchEvaluator je zjevně velmi mocný nástroj a toto je pouze jednoduchý příklad toho, čeho lze dosáhnout.

Shrnutí

Operace vyhledávání a nahrazení se stávají velmi mocnými, když používáte regulární výrazy, a ještě více, když používáte parametr MatchEvaluator, kde se možnosti manipulace s řetězci stávají téměř neomezenými.


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!