Poznáváme C# a Microsoft. NET 31. díl – regulární výrazy

Minule jsme se seznámili s pojmem regulární výraz. V tomto díle se na možné použití regulárních výrazů a jejich aplikaci v rámci .NET podíváme trochu blíže.

V minulém úvodu do světa regulárních výrazů jsme se zatím naučili zjistit, jestli řetězec obsahuje nějaký podřetězec a zjistit jeho pozici v prohledávaném řetězci. Kdyby byly možnosti regulárních výrazů takto omezené, nebyl by smysl k jejich užití. Regulární výrazy nám, ale nabízejí spoustu užitečných funkcí.

Libovolné znaky v regulárních výrazech

V regulárním výrazu máme možnost určit, že na nějakých místech v řetězci mohou být libovolné znaky. K vyjádření libovolného znaku slouží zástupný symbol . (tečka). Tento symbol nám dovoluje vyjádřit, že na daném místě se může vyskytovat jeden libovolný znak. Pokud je naše přání takové, že chceme povolit neomezený počet určitých znaků použijeme symbolu * (hvězda) . Následující příklad ukazuje možné použití těchto symbolů v regulárním výrazu, jehož pomocí je zjišťováno, zda řetězec představuje emailovou adresu.

/// <summary>
/// Zjisti, zda-li predany retezec predstavuje emailovou adresu
/// pouzitim regularniho vyrazu
/// </summary>
/// <param name="Retezec">Vstupni retezec</param>
public static bool JeEmail(string Retezec)
{
  Regex lRegEx = new Regex(@"
.*@.*\..*");
  return lRegEx.IsMatch(Retezec);
}

public static void PrikladEmail()
{
  string[] lHodnoty = {"
petr.pus@unicorn.cz","jouda#joudove.cz","spatna@adresa"};
  foreach(string lHodnota in lHodnoty)
  {
    if (JeEmail(lHodnota))
      Console.WriteLine("Retezec {0} predstavuje emailovou adresu.",lHodnota);
    else
      Console.WriteLine("Retezec {0} nepredstavuje emailovou adresu.",lHodnota);
  }
}

Regulární výraz .*@.*\..* určuje, že řetězec může začínat libovolným počtem libovolných znaků (.* - tečka je libovolný znak a hvězda říká, že jich může být libovolný počet), po té musí následovat znak zavináče, po něm opět libovolný počet znaků, potom tečka a zase libovolné znaky. Tento příklad mimo jiné demonstruje způsob použití znaku tečka jako součásti regulárního výrazu.

Pokud chceme určit, že se má v řetězci vyskytovat tečka jako znak, nemůžeme jednoduše napsat tečku do výrazu protože by byla chápána jako možnost libovolného znaku. Proto je pro vyjádření tečky použito zpětného lomítka (\.). Z důvodu výskytu zpětného lomítka musíme zabránit tomu, aby tato část řetězce nebyla brána jako tzv. escape-sekvence a to provedeme použitím vlastnosti jazyka C#, kterou je použití znaku zavináč před řetězcem. V takto označeném řetězci pak nejsou escape-sekvence zpracovávány.

Intervaly znaků

Další možností je specifikovat množinu určitých znaků v regulárním výrazu. K tomuto účelu slouží dvojice hranatých závorek mezi kterými je uveden námi požadovaný výčet znaků nebo je také možné specifikovat interval, kde uvedeme počáteční a koncový znak onoho intervalu a oddělíme je pomlčkou. To znamená, že regulárnímu výrazu ve tvaru [aeiou] vyhoví pouze znaky a,e,i,o,u a pokud využijeme druhé možnosti, tj. určení intervalu tak výrazu [a-e] vyhoví pouze znaky a až e naší abecedy. Následující příklad zjišťuje, jestli řetězec představuje číslo a to právě pomocí definovaného intervalu znaků.

/// <summary>
/// Zjisti, zda-li predany retezec predstavuje cislo
/// pouzitim regularniho vyrazu
/// </summary>
/// <param name="Retezec">Vstupni retezec</param>
public static bool JeCislo(string Retezec)
{
//pokud je v retezci jediny znak ruzny od cisla vyhovi regularnimu vyrazu
  Regex lReg = new Regex("[^0-9]");
  //pokud se v retezci nevyskytl zadny znak ruzny od cisla je to v poradku
  return !lReg.IsMatch(Retezec);
}
public static void PrikladCislo()
{
  string[] lHodnoty = {"0123455789","12ab12"};
  foreach(string lHodnota in lHodnoty)
  {
    if (JeCislo(lHodnota))
      Console.WriteLine("Retezec {0} predstavuje cislo.",lHodnota);
    else
      Console.WriteLine("Retezec {0} nepredstavuje cislo.",lHodnota);
  }
}

Výstup po spuštění tohoto příkladu by měl vypadat takto:

Retezec 0123455789 predstavuje cislo.
Retezec 12ab12 nepredstavuje cislo.

V regulárním výrazu, který je uveden v příkladu se objevuje znak ^ (stříška), který v jazyku regulárních výrazů znamená negaci. Takže použití regulárního výrazu [^0-9] ve výsledku zapříčiní, že pokud se v řetězci nachází alespoň jeden znak různý od čísel nula až devět, bude tento řetězec regulárnímu výrazu vyhovovat.

Skupiny v regulárních výrazech

V regulárních výrazech se nám nabízí využití skupin ve vyhledávaném výrazu. Tyto skupiny využijeme v případě, že potřebujeme získat pouze část nalezeného řetězce. Skupiny jsou v regulárních výrazech tvořeny pomocí závorek. Následující příklad ukazuje použití skupin v regulárním výrazu pro získání a zvýšení hodnoty v korunách, která je představována řetězcem.

/// <summary>
/// Zjisti zda predany retezec predstavuje hodnotu v korunach a umoznuje
/// k teto hodnote pridan urcity pocet korun.
/// </summary>
public static void PrikladKoruny(string Retezec,int PridanaHodnota)
{
  Regex lRegEx = new Regex(@"\b(\d+)\.(\d\d)Kc\b");
  Match lMatch = lRegEx.Match(Retezec);
  if (lMatch.Success)
  {
    GroupCollection lGroupCol = lMatch.Groups;
    int lNovaHodnota = Int32.Parse(lGroupCol[1].Value) + PridanaHodnota;
    Console.WriteLine("Hodnota po pricteni {0} korun je {1},{2}",PridanaHodnota,lNovaHodnota,lGroupCol[2]);
  }
  else
    Console.WriteLine("Retezec nevyhovuje");
}

Regulární výraz \b(\d+)\.(\d\d)Kc\b , který je použit v tomto příkladu definuje dvě skupiny. První skupina je tvořena libovolným počtem číslic (\d+ - symbol \d znamená totéž jako interval [0-9] a ono plus říká, že jich může být libovolný počet) představující koruny a druhá dvěma libovolnými číslicemi představující haléře. Hodnota korun a haléřů musí být oddělena tečkou.

Dalším dosud nevysvětleným symbolem, který je v příkladu použit je symbol \b a ten značí pomyslné hranice řetězce. Protože pokud bych tento znak ve výrazu nepoužil, tak by před nebo za hodnotou mohli být jakékoli jiné znaky a řetězec by stejně výrazu vyhověl, poněvadž k vyhovění regulárního výrazu stačí, aby řetězec obsahoval podřetězec splňující vzor. Tímto symbolem tedy v jazyce regulárních výrazů řekneme, že před ani za řetězcem splňující námi dané podmínky se již nesmí nic jiného nacházet.

Třídu Match ze jmenného prostoru System.Text.RegularExpressions známe již z minulého dílu. Novinkou při použití skupin v regulárních výrazech je ovšem třída GroupCollection , která představujíce kolekci všech skupin z vyhovujícího řetězce. V našem ukázkovém příkladu to budou skupiny tři (první skupina je celý vyhovující výraz, druhá jsou koruny a třetí haléře). Každá skupina je reprezentována instancí třídy Group a v příkladu je získána použitím indexeru definovaným na třídě GroupCollection. Pro kýžené přidání hodnoty je tedy vzata hodnota korun, převedena na typ Int32 a k ní je po té přičteno.

Zdrojové kódy k příkladům naleznete zde.

Diskuze (7) Další článek: Microsoft Windows 2000 Server přešel do prodloužené fáze technické podpory

Témata článku: Software, Microsoft, Programování, Public, Escape, Elsa, Znak, Libovolný znak, Regulární výraz, Díl, Match, Escape sekvence, Libovolné místo


Určitě si přečtěte

Srovnali jsme česká města s IBM, Googlem nebo třeba Samsungem. Podívejte se, v jaké firmě „žijete“

Srovnali jsme česká města s IBM, Googlem nebo třeba Samsungem. Podívejte se, v jaké firmě „žijete“

** Nadnárodní korporace zaměstnávají stovky tisíc lidí ** Mají tedy velikost metropolí ** Srovnali jsme je s českými krajskými městy

Jakub Čížek | 14

Co všechno se spouští se startem Windows a proč by vás to mělo zajímat

Co všechno se spouští se startem Windows a proč by vás to mělo zajímat

** Společně s operačním systémem se spouští řada aplikací a služeb ** Mohou mít negativní dopad na celkovou dobu startu Windows ** Jak získat kontrolu nad automaticky spouštěnými programy?

Karel Kilián | 60

Pozor, na Česko v těchto dnech útočí falešné Tesco, Penny Market a Lidl

Pozor, na Česko v těchto dnech útočí falešné Tesco, Penny Market a Lidl

** Máme tu další českou phishingovou vlnu ** Podle průzkumů máme stále problém s kybernetickou gramotností ** Nebezpečím jsou děti, které opouštějí rodiče

Jakub Čížek | 37

Měření rychlosti internetu: Populární Speedtest.net neřekne o skutečné rychlosti internetu téměř nic

Měření rychlosti internetu: Populární Speedtest.net neřekne o skutečné rychlosti internetu téměř nic

** Speedtest stále častěji měří jen rychlost na poslední míli ** Ta však ale neodpovídá reálnému surfování ** Jak se tedy pokusit změřit tu skutečnou?

Jakub Čížek | 85



Aktuální číslo časopisu Computer

Test 9 bezdrátových reproduktorů

Jak ovládnout Instagram

Test levných 27" herních monitorů

Jak se zbavit nepotřebných věcí na internetu