This article has been localized into Czech by the community.
Regex modifikátory
V předchozích článcích jsme mluvili o tom, co jsou regulární výrazy a jak je používat v C# pro porovnávání, nahrazování a tak dále. V tomto okamžiku byste již měli pochopit, jak mocné regulární výrazy jsou a jak vám mohou pomoci v mnoha situacích, ale stávají se ještě mocnějšími, když znáte možné modifikátory.
Při práci s regulárními výrazy můžete použít jeden nebo několik modifikátorů pro řízení chování vyhledávacího mechanismu. Například proces vyhledávání s regulárními výrazy je obvykle citlivý na velikost písmen, což znamená, že "a" není totéž co "A". Nicméně, v mnoha situacích chcete, aby vaše vyhledávání bylo necitlivé na velikost písmen, takže znak "a" je prostě písmeno, ať už je malé nebo VELKÉ. Stačí při vytváření instance Regex dodat možnost RegexOptions.IgnoreCase a vaše vyhledávání bude necitlivé na velikost písmen.
Všechny dostupné modifikátory naleznete ve výčtu RegexOptions. Několik z nich je společných pro všechny programovací jazyky podporující standard regulárních výrazů, zatímco jiné jsou specifické pro .NET framework.
Jak uvidíte v prvním příkladu, modifikátory Regex jsou obvykle specifikovány jako druhý parametr při vytváření instance Regex. Můžete určit více než jednu možnost oddělením pomocí znaku svislítka (pipe) (|), jako například:
new Regex("[a-z]+", RegexOptions.IgnoreCase | RegexOptions.Singleline);
Nyní projdeme všechny modifikátory, abychom vám dali představu o tom, jak fungují a co pro vás mohou udělat.
RegexOptions.IgnoreCase
Tento modifikátor pravděpodobně budete používat velmi často. Jak bylo popsáno výše, změní vaše regulární výrazy z rozlišování malých a velkých písmen na nerozlišování malých a velkých písmen. To dělá velký rozdíl, jak můžete vidět na tomto příkladu:
public void IgnoreCaseModifier()
{
string testString = "Hello World";
string regexString = @"^[a-z\s]+$";
Regex caseSensitiveRegex = new Regex(regexString);
Regex caseInsensitiveRegex = new Regex(regexString, RegexOptions.IgnoreCase);
Console.WriteLine("Case-sensitive match: " + caseSensitiveRegex.IsMatch(testString));
Console.WriteLine("Case-insensitive match: " + caseInsensitiveRegex.IsMatch(testString));
}
Určujeme jednoduchý regulární výraz, který má odpovídat pouze písmenům (a-z) a mezerám. Používáme ho k vytvoření dvou instancí Regex: jedné bez modifikátoru RegexOptions.IgnoreCase a jedné s ním, a pak se pokoušíme porovnat stejný testovací řetězec, který se skládá z malých a VELKÝCH písmen a jedné mezery. Výstup bude, pravděpodobně nepřekvapivě, vypadat takto:
Case-sensitive match: False
Case-insensitive match: True
RegexOptions.Singleline
V regulárních výrazech je tečka (.) v podstatě univerzálním znakem. Ve výchozím nastavení však neodpovídá zalamování řádků, což znamená, že můžete použít tečku k odpovídání celého řádku písmen, čísel, speciálních znaků a tak dále, ale shoda skončí, jakmile narazí na zalomení řádku. Pokud však použijete modifikátor Singleline, tečka bude odpovídat i zalomením řádků. Dovolte mi demonstrovat rozdíl:
public void SinglelineModifier()
{
string testString =
@"Hello World
This string contains
several lines";
string regexString = ".*";
Regex normalRegex = new Regex(regexString);
Regex singlelineRegex = new Regex(regexString, RegexOptions.Singleline);
Console.WriteLine("Normal regex: " + normalRegex.Match(testString).Value);
Console.WriteLine("Singleline regex: " + singlelineRegex.Match(testString).Value);
}
Výstup vypadá takto:
Normal regex: Hello World
Singleline regex: Hello World
This string contains
several lines
RegexOptions.Multiline
Jak jsme již v této kapitole diskutovali, regulární výrazy se skládají z mnoha různých znaků, které mají speciální účely. Dalším příkladem toho jsou tyto dva znaky: ^ a $. Ve výše uvedeném příkladu o citlivosti na velká a malá písmena jsme je skutečně použili k odpovídání začátku a konce řetězce. Dodáním modifikátoru Multiline však můžete toto chování změnit z odpovídání na začátek/konec řetězce na odpovídání na začátek/konec řádků. To je velmi užitečné, když chcete jednotlivě zacházet s odpovídajícími řádky. Zde je příklad:
public void MultilineModifier()
{
string testString =
@"Hello World
This string contains
several lines";
string regexString = "^.*$";
Regex singlelineRegex = new Regex(regexString, RegexOptions.Singleline);
Regex multilineRegex = new Regex(regexString, RegexOptions.Multiline);
Console.WriteLine("Singleline regex: " + singlelineRegex.Match(testString).Value);
Console.WriteLine("Multiline regex:");
MatchCollection matches = multilineRegex.Matches(testString);
for(int i = 0; i < matches.Count; i++)
Console.WriteLine("Line " + i + ": " + matches[i].Value.Trim());
}
Všimněte si, jak používám testovací řetězec sestávající z několika řádků a poté používám mechanismy shody různě: S singlelineRegex považujeme celý testovací řetězec za jeden řádek, i když obsahuje zalomení řádků, jak jsme již výše diskutovali. Při použití multilineRegex považujeme testovací řetězec za více řádků, z nichž každý vede k shodě. Můžeme použít metodu Regex.Matches() k zachycení každého řádku a pracovat s ním - v tomto případě jej jednoduše vypíšeme na konzolu.
RegexOptions.Compiled
I když jsou regulární výrazy obecně poměrně rychlé, mohou trochu zpomalit, pokud jsou velmi složité a vykonávají se mnohokrát, například v cyklu. Pro tyto situace můžete chtít použít modifikátor RegexOptions.Compiled, který umožní frameworku kompilovat regulární výraz do sestavení. Toto má o něco vyšší nároky na čas, když jej vytváříte, ve srovnání s obyčejným vytvořením objektu Regex, ale všechny následující operace s regulárními výrazy (shody atd.) budou rychlejší.
Regex compiledRegex = new Regex("[a-z]*", RegexOptions.Compiled);
Více modifikátorů
Nahoře uvedené modifikátory jsou nejzajímavější, ale existuje ještě několik dalších, které projdeme trochu rychleji:
- RegexOptions.CultureInvariant: S tímto modifikátorem se ignorují kulturní rozdíly v jazyce. To je většinou relevantní, pokud vaše aplikace pracuje s více neanglickými jazyky. Tento modifikátor zajišťuje, že regulární výraz bude interpretován bez ohledu na aktuální kulturní nebo jazykové nastavení, což je užitečné pro zajištění konzistentního chování regulárního výrazu napříč různými lokalitami a jazyky.
- RegexOptions.ECMAScript: Změní variantu Regex používanou z verze specifické pro .NET na standard ECMAScript. To by mělo být zřídka nutné.
- RegexOptions.ExplicitCapture: Obvykle skupina závorek v regulárním výrazu funguje jako zachytávající skupina, což vám umožňuje přistupovat ke každé zachycené hodnotě prostřednictvím indexu. Pokud specifikujete modifikátor ExplicitCapture, toto chování se změní tak, že jsou zachyceny a uloženy pro pozdější načtení pouze pojmenované skupiny.
- RegexOptions.IgnorePatternWhitespace: Když je tento modifikátor povolen, bílé znaky v regulárním výrazu jsou ignorovány a dokonce můžete zahrnout komentáře, které jsou označeny znakem mřížky (#).
- RegexOptions.RightToLeft: Změní způsob hledání tak, že začíná zprava a pokračuje doleva, místo výchozího směru zleva doprava.
Shrnutí
Jak vidíte, existuje mnoho důležitých modifikátorů Regex, o kterých byste měli vědět, abyste mohli plně využít regulární výrazy, aby podporovaly co nejvíce případů použití.