Podrobnosti o chování regulárního výrazu

Modul regulárních výrazů .NET je modul pro zpětné navracení shody regulárních výrazů, který zahrnuje tradiční nedeterministický automaton (NFA), jako je perl, Python, Emacs a Tcl. Tím se odlišují od rychlejších, ale omezenějších, čistě regulárních výrazů deterministických finistických automatonů (DFA), jako jsou moduly nalezené v awk, egrep nebo lex. To také odlišuje od standardizovaných, ale pomalejších, POSIX NFAs. Následující část popisuje tři typy modulů regulárních výrazů a vysvětluje, proč jsou regulární výrazy v .NET implementovány pomocí tradičního modulu NFA.

Výhody modulu NFA

Když moduly DFA provádějí porovnávání vzorů, jejich pořadí zpracování je řízeno vstupním řetězcem. Modul začíná na začátku vstupního řetězce a postupně zjišťuje, jestli další znak odpovídá vzoru regulárního výrazu. Můžou zaručit, že odpovídají nejdelšímu možnému řetězci. Protože nikdy neotestují stejný znak dvakrát, moduly DFA nepodporují navracení. Vzhledem k tomu, že modul DFA obsahuje pouze konečný stav, nemůže se shodovat se vzory s backreferencemi, a protože nevytyčuje explicitní rozšíření, nemůže zachytit dílčí výrazy.

Na rozdíl od modulů DFA se při porovnávání vzorů tradičních modulů NFA řídí jejich pořadí zpracování vzorem regulárního výrazu. Při zpracování určitého prvku jazyka modul používá porovnávání greedy; to znamená, že odpovídá tolik vstupnímu řetězci, kolik to může. Ale také uloží svůj stav po úspěšném párování dílčího výrazu. Pokud se shoda nakonec nezdaří, modul se může vrátit do uloženého stavu, aby mohl vyzkoušet další shody. Tento proces opuštění úspěšné shody dílčího výrazu tak, aby se pozdější prvky jazyka v regulárním výrazu mohly shodovat, se také označuje jako zpětné navracení. Moduly NFA používají zpětné navracení k otestování všech možných rozšíření regulárního výrazu v určitém pořadí a přijímají první shodu. Vzhledem k tomu, že tradiční modul NFA vytváří konkrétní rozšíření regulárního výrazu pro úspěšnou shodu, může zachytit shody dílčího výrazu a odpovídající backreference. Vzhledem k tomu, že tradiční navracení NFA může několikrát navštívit stejný stav, pokud dorazí do stavu přes různé cesty. V důsledku toho může v nejhorším případě běžet exponenciálně pomalu. Vzhledem k tomu, že tradiční modul NFA přijímá první nalezenou shodu, může také ponechat jiné (pravděpodobně delší) shody neobjevené.

Moduly POSIX NFA jsou podobné tradičním modulům NFA, s tím rozdílem, že se budou dál vracet, dokud nebudou moci zaručit, že našli nejdelší možnou shodu. V důsledku toho je modul POSIX NFA pomalejší než tradiční modul NFA a při použití modulu POSIX NFA nemůžete upřednostňovat kratší shodu po delší dobu změnou pořadí hledání zpětného navracení.

Tradiční moduly NFA jsou preferovány programátory, protože nabízejí větší kontrolu nad porovnáváním řetězců než moduly DFA nebo POSIX NFA. I když v nejhorším případě můžou běžet pomalu, můžete je ztlumit a najít shody v lineárním nebo polynomickém čase pomocí vzorů, které snižují nejednoznačnosti a omezují navracení. Jinými slovy, i když moduly NFA obchodují s výkonem a flexibilitou, ve většině případů nabízejí přijatelný výkon, pokud je regulární výraz dobře napsaný a zabraňuje případům, kdy navracení snižuje výkon exponenciálně.

Poznámka:

Informace o penalizaci výkonu způsobené nadměrným navracením a způsoby vytvoření regulárního výrazu, který se s nimi dá obejít, najdete v tématu Navracení.

Možnosti modulu .NET

Aby bylo možné využít výhod tradičního modulu NFA, modul regulárních výrazů .NET obsahuje kompletní sadu konstruktorů, aby programátoři mohli modul zpětného navracení ztlumit. Tyto konstrukce lze použít k rychlejšímu vyhledání shody nebo k upřednostnění konkrétních rozšíření oproti ostatním.

Mezi další funkce modulu regulárních výrazů .NET patří:

  • Opožděné kvantifikátory: ??, *?, +?{n,m.}? Tyto konstrukce říkají backtracking modulu, aby nejprve prohledál minimální počet opakování. Naproti tomu běžné kvantifikátory greedy se snaží nejprve shodovat s maximálním počtem opakování. Následující příklad znázorňuje rozdíl mezi těmito dvěma. Regulární výraz odpovídá větě, která končí číslem, a zachytávaná skupina je určená k extrahování daného čísla. Regulární výraz .+(\d+)\. obsahuje kvantifikátor .+greedy, který způsobí, že modul regulárních výrazů zachytí pouze poslední číslici čísla. Regulární výraz .+?(\d+)\. naproti tomu obsahuje opožděný kvantifikátor .+?, který způsobí, že modul regulárních výrazů zachytí celé číslo.

    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
        public static void Main()
        {
            string greedyPattern = @".+(\d+)\.";
            string lazyPattern = @".+?(\d+)\.";
            string input = "This sentence ends with the number 107325.";
            Match match;
    
            // Match using greedy quantifier .+.
            match = Regex.Match(input, greedyPattern);
            if (match.Success)
                Console.WriteLine("Number at end of sentence (greedy): {0}",
                                  match.Groups[1].Value);
            else
                Console.WriteLine("{0} finds no match.", greedyPattern);
    
            // Match using lazy quantifier .+?.
            match = Regex.Match(input, lazyPattern);
            if (match.Success)
                Console.WriteLine("Number at end of sentence (lazy): {0}",
                                  match.Groups[1].Value);
            else
                Console.WriteLine("{0} finds no match.", lazyPattern);
        }
    }
    // The example displays the following output:
    //       Number at end of sentence (greedy): 5
    //       Number at end of sentence (lazy): 107325
    
    Imports System.Text.RegularExpressions
    
    Module Example
        Public Sub Main()
            Dim greedyPattern As String = ".+(\d+)\."
            Dim lazyPattern As String = ".+?(\d+)\."
            Dim input As String = "This sentence ends with the number 107325."
            Dim match As Match
    
            ' Match using greedy quantifier .+.
            match = Regex.Match(input, greedyPattern)
            If match.Success Then
                Console.WriteLine("Number at end of sentence (greedy): {0}",
                                  match.Groups(1).Value)
            Else
                Console.WriteLine("{0} finds no match.", greedyPattern)
            End If
    
            ' Match using lazy quantifier .+?.
            match = Regex.Match(input, lazyPattern)
            If match.Success Then
                Console.WriteLine("Number at end of sentence (lazy): {0}",
                                  match.Groups(1).Value)
            Else
                Console.WriteLine("{0} finds no match.", lazyPattern)
            End If
        End Sub
    End Module
    ' The example displays the following output:
    '       Number at end of sentence (greedy): 5
    '       Number at end of sentence (lazy): 107325
    

    Greedy a opožděné verze tohoto regulárního výrazu jsou definovány, jak je znázorněno v následující tabulce:

    Vzor Popis
    .+ (kvantifikátor greedy) Porovná alespoň jeden výskyt libovolného znaku. To způsobí, že modul regulárních výrazů odpovídá celému řetězci, a pak se podle potřeby vrátí zpět, aby odpovídal zbytku vzoru.
    .+? (opožděný kvantifikátor) Porovná alespoň jeden výskyt libovolného znaku, ale musí odpovídat co nejmenšímu počtu znaků.
    (\d+) Porovná alespoň jeden číselný znak a přiřadí ho první zachycené skupině.
    \. Porovná období.

    Další informace o opožděných kvantifikátorů najdete v tématu Kvantifikátory.

  • Pozitivní pohled: (?=dílčí výraz). Tato funkce umožňuje modulu zpětného navracení vrátit se po párování dílčího výrazu na stejné místo v textu. Je užitečné pro hledání v celém textu ověřením více vzorů, které začínají na stejné pozici. Umožňuje také modulu ověřit, že podřetětěr existuje na konci shody bez zahrnutí podřetětěce do odpovídajícího textu. Následující příklad používá pozitivní pohled k extrahování slov ve větě, za kterou následují symboly interpunkce.

    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
        public static void Main()
        {
            string pattern = @"\b[A-Z]+\b(?=\P{P})";
            string input = "If so, what comes next?";
            foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
                Console.WriteLine(match.Value);
        }
    }
    // The example displays the following output:
    //       If
    //       what
    //       comes
    
    Imports System.Text.RegularExpressions
    
    Module Example
        Public Sub Main()
            Dim pattern As String = "\b[A-Z]+\b(?=\P{P})"
            Dim input As String = "If so, what comes next?"
            For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
                Console.WriteLine(match.Value)
            Next
        End Sub
    End Module
    ' The example displays the following output:
    '       If
    '       what
    '       comes
    

    Regulární výraz \b[A-Z]+\b(?=\P{P}) je definován, jak je znázorněno v následující tabulce.

    Vzor Popis
    \b Začne porovnání na hranici slova.
    [A-Z]+ Porovná libovolný abecední znak jednou nebo vícekrát. Vzhledem k tomu, že Regex.Matches metoda je volána s RegexOptions.IgnoreCase možností, porovnání nerozlišuje malá a velká písmena.
    \b Ukončí porovnání na hranici slova.
    (?=\P{P}) Podívejte se, jestli je dalším znakem interpunkční znaméčko. Pokud tomu tak není, shoda bude úspěšná.

    Další informace o pozitivních kontrolních výrazech pro vyhledávání naleznete v tématu Seskupování konstruktorů.

  • Negativní pohled: (?!dílčí výraz). Tato funkce přidá možnost spárovat výraz pouze v případě, že se dílčí výraz neshoduje. To je účinné pro vyřazování hledání, protože často je jednodušší zadat výraz pro případ, který by měl být odstraněn než výraz pro případy, které musí být zahrnuty. Například je obtížné napsat výraz pro slova, která nezačínají slovem "non". Následující příklad používá negativní pohled k vyloučení.

    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
        public static void Main()
        {
            string pattern = @"\b(?!non)\w+\b";
            string input = "Nonsense is not always non-functional.";
            foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
                Console.WriteLine(match.Value);
        }
    }
    // The example displays the following output:
    //       is
    //       not
    //       always
    //       functional
    
    Imports System.Text.RegularExpressions
    
    Module Example
        Public Sub Main()
            Dim pattern As String = "\b(?!non)\w+\b"
            Dim input As String = "Nonsense is not always non-functional."
            For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
                Console.WriteLine(match.Value)
            Next
        End Sub
    End Module
    ' The example displays the following output:
    '       is
    '       not
    '       always
    '       functional
    

    Vzor regulárního výrazu \b(?!non)\w+\b je definován, jak je znázorněno v následující tabulce.

    Vzor Popis
    \b Začne porovnání na hranici slova.
    (?!non) Podívejte se dopředu, abyste zajistili, že aktuální řetězec nezačíná na "non". Pokud ano, shoda selže.
    (\w+) Porovná jeden nebo více znaků slova.
    \b Ukončí porovnání na hranici slova.

    Další informace o negativních kontrolních výrazech pro vyhledávání naleznete v tématu Seskupování konstruktorů.

  • Podmíněné vyhodnocení: (?(výraz)ano|ne) a (?(název)ano|ne), kde výraz je dílčí výraz, který se má shodovat, název je název zachytávání skupiny, ano je řetězec, který se má shodovat, pokud se výraz shoduje nebo název je platná, neprázdná zachycená skupina a ne. neodpovídá nebo název není platná, neprázdná zachycená skupina. Tato funkce umožňuje modulu vyhledávat pomocí více než jednoho alternativního vzoru v závislosti na výsledku předchozí shody dílčího výrazu nebo výsledku kontrolního výrazu nulové šířky. To umožňuje výkonnější formu zpětného odvození, která umožňuje například párování dílčího výrazu na základě toho, zda byl předchozí dílčí výraz spárován. Regulární výraz v následujícím příkladu odpovídá odstavcům určeným pro veřejné i interní použití. Odstavce určené pouze pro interní použití začínají značkou <PRIVATE> . Vzor ^(?<Pvt>\<PRIVATE\>\s)?(?(Pvt)((\w+\p{P}?\s)+)|((\w+\p{P}?\s)+))\r?$ regulárního výrazu používá podmíněné vyhodnocení k přiřazení obsahu odstavců určených pro veřejné a interní použití k oddělení zachycených skupin. Tyto odstavce je pak možné zpracovat jinak.

    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
        public static void Main()
        {
            string input = "<PRIVATE> This is not for public consumption." + Environment.NewLine +
                           "But this is for public consumption." + Environment.NewLine +
                           "<PRIVATE> Again, this is confidential.\n";
            string pattern = @"^(?<Pvt>\<PRIVATE\>\s)?(?(Pvt)((\w+\p{P}?\s)+)|((\w+\p{P}?\s)+))\r?$";
            string publicDocument = null, privateDocument = null;
    
            foreach (Match match in Regex.Matches(input, pattern, RegexOptions.Multiline))
            {
                if (match.Groups[1].Success)
                {
                    privateDocument += match.Groups[1].Value + "\n";
                }
                else
                {
                    publicDocument += match.Groups[3].Value + "\n";
                    privateDocument += match.Groups[3].Value + "\n";
                }
            }
    
            Console.WriteLine("Private Document:");
            Console.WriteLine(privateDocument);
            Console.WriteLine("Public Document:");
            Console.WriteLine(publicDocument);
        }
    }
    // The example displays the following output:
    //    Private Document:
    //    This is not for public consumption.
    //    But this is for public consumption.
    //    Again, this is confidential.
    //
    //    Public Document:
    //    But this is for public consumption.
    
    Imports System.Text.RegularExpressions
    
    Module Example
        Public Sub Main()
            Dim input As String = "<PRIVATE> This is not for public consumption." + vbCrLf + _
                                  "But this is for public consumption." + vbCrLf + _
                                  "<PRIVATE> Again, this is confidential." + vbCrLf
            Dim pattern As String = "^(?<Pvt>\<PRIVATE\>\s)?(?(Pvt)((\w+\p{P}?\s)+)|((\w+\p{P}?\s)+))\r?$"
            Dim publicDocument As String = Nothing
            Dim privateDocument As String = Nothing
    
            For Each match As Match In Regex.Matches(input, pattern, RegexOptions.Multiline)
                If match.Groups(1).Success Then
                    privateDocument += match.Groups(1).Value + vbCrLf
                Else
                    publicDocument += match.Groups(3).Value + vbCrLf
                    privateDocument += match.Groups(3).Value + vbCrLf
                End If
            Next
    
            Console.WriteLine("Private Document:")
            Console.WriteLine(privateDocument)
            Console.WriteLine("Public Document:")
            Console.WriteLine(publicDocument)
        End Sub
    End Module
    ' The example displays the following output:
    '    Private Document:
    '    This is not for public consumption.
    '    But this is for public consumption.
    '    Again, this is confidential.
    '    
    '    Public Document:
    '    But this is for public consumption.
    

    Vzor regulárního výrazu je definován, jak je znázorněno v následující tabulce.

    Vzor Popis
    ^ Zahajte shodu na začátku řádku.
    (?<Pvt>\<PRIVATE\>\s)? Porovná žádný nebo jeden výskyt řetězce <PRIVATE> následovaného prázdným znakem. Přiřaďte shodu k zachycené skupině s názvem Pvt.
    (?(Pvt)((\w+\p{P}?\s)+) Pvt Pokud skupina zachycení existuje, porovná jeden nebo více výskytů jednoho nebo více znaků slova následovaných nulou nebo jedním oddělovačem interpunkce následovaným prázdným znakem. Přiřaďte podřetěc k první skupině zachycení.
    |((\w+\p{P}?\s)+)) Pvt Pokud skupina zachytávání neexistuje, porovná jeden nebo více výskytů jednoho nebo více znaků slova následovaných nulou nebo jedním oddělovačem interpunkce následovaným prázdným znakem. Přiřaďte podřetěc třetí skupině zachycení.
    \r?$ Porovná konec řádku nebo konce řetězce.

    Další informace o podmíněném vyhodnocení naleznete v tématu Alternace konstruktorů.

  • Definice skupiny vyrovnávání: (?<podvýraz) name1-name2> Tato funkce umožňuje modulu regulárních výrazů sledovat vnořené konstrukce, jako jsou závorky nebo levá a pravá hranatá závorka. Příklad najdete v tématu Seskupování konstruktorů.

  • Atomické skupiny: (?>dílčí výraz). Tato funkce umožňuje modulu zpětného navracení zaručit, že dílčí výraz odpovídá pouze první shodě nalezené pro daný dílčí výraz, jako by byl výraz spuštěn nezávisle na jeho obsahujícím výrazu. Pokud tento konstruktor nepoužíváte, vyhledávání zpětného navracení z většího výrazu může změnit chování dílčího výrazu. Regulární výraz (a+)\w například odpovídá jednomu nebo více znakům "a" spolu se znakem slova, který následuje za posloupností znaků "a" a přiřadí sekvenci znaků "a" první skupině zachycení. Pokud je ale posledním znakem vstupního řetězce také "a", odpovídá \w elementu jazyka a není součástí zachycené skupiny.

    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
        public static void Main()
        {
            string[] inputs = { "aaaaa", "aaaaab" };
            string backtrackingPattern = @"(a+)\w";
            Match match;
    
            foreach (string input in inputs)
            {
                Console.WriteLine("Input: {0}", input);
                match = Regex.Match(input, backtrackingPattern);
                Console.WriteLine("   Pattern: {0}", backtrackingPattern);
                if (match.Success)
                {
                    Console.WriteLine("      Match: {0}", match.Value);
                    Console.WriteLine("      Group 1: {0}", match.Groups[1].Value);
                }
                else
                {
                    Console.WriteLine("      Match failed.");
                }
            }
            Console.WriteLine();
        }
    }
    // The example displays the following output:
    //       Input: aaaaa
    //          Pattern: (a+)\w
    //             Match: aaaaa
    //             Group 1: aaaa
    //       Input: aaaaab
    //          Pattern: (a+)\w
    //             Match: aaaaab
    //             Group 1: aaaaa
    
    Imports System.Text.RegularExpressions
    
    Module Example
        Public Sub Main()
            Dim inputs() As String = {"aaaaa", "aaaaab"}
            Dim backtrackingPattern As String = "(a+)\w"
            Dim match As Match
    
            For Each input As String In inputs
                Console.WriteLine("Input: {0}", input)
                match = Regex.Match(input, backtrackingPattern)
                Console.WriteLine("   Pattern: {0}", backtrackingPattern)
                If match.Success Then
                    Console.WriteLine("      Match: {0}", match.Value)
                    Console.WriteLine("      Group 1: {0}", match.Groups(1).Value)
                Else
                    Console.WriteLine("      Match failed.")
                End If
            Next
            Console.WriteLine()
        End Sub
    End Module
    ' The example displays the following output:
    '       Input: aaaaa
    '          Pattern: (a+)\w
    '             Match: aaaaa
    '             Group 1: aaaa
    '       Input: aaaaab
    '          Pattern: (a+)\w
    '             Match: aaaaab
    '             Group 1: aaaaa
    

    Regulární výraz ((?>a+))\w zabraňuje tomuto chování. Vzhledem k tomu, že všechny po sobě jdoucí znaky "a" se shodují bez zpětného navracení, první skupina zachycení obsahuje všechny po sobě jdoucí znaky "a". Pokud za znaky "a" nepřijde aspoň jeden další znak než "a", shoda se nezdaří.

    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
        public static void Main()
        {
            string[] inputs = { "aaaaa", "aaaaab" };
            string nonbacktrackingPattern = @"((?>a+))\w";
            Match match;
    
            foreach (string input in inputs)
            {
                Console.WriteLine("Input: {0}", input);
                match = Regex.Match(input, nonbacktrackingPattern);
                Console.WriteLine("   Pattern: {0}", nonbacktrackingPattern);
                if (match.Success)
                {
                    Console.WriteLine("      Match: {0}", match.Value);
                    Console.WriteLine("      Group 1: {0}", match.Groups[1].Value);
                }
                else
                {
                    Console.WriteLine("      Match failed.");
                }
            }
            Console.WriteLine();
        }
    }
    // The example displays the following output:
    //       Input: aaaaa
    //          Pattern: ((?>a+))\w
    //             Match failed.
    //       Input: aaaaab
    //          Pattern: ((?>a+))\w
    //             Match: aaaaab
    //             Group 1: aaaaa
    
    Imports System.Text.RegularExpressions
    
    Module Example
        Public Sub Main()
            Dim inputs() As String = {"aaaaa", "aaaaab"}
            Dim nonbacktrackingPattern As String = "((?>a+))\w"
            Dim match As Match
    
            For Each input As String In inputs
                Console.WriteLine("Input: {0}", input)
                match = Regex.Match(input, nonbacktrackingPattern)
                Console.WriteLine("   Pattern: {0}", nonbacktrackingPattern)
                If match.Success Then
                    Console.WriteLine("      Match: {0}", match.Value)
                    Console.WriteLine("      Group 1: {0}", match.Groups(1).Value)
                Else
                    Console.WriteLine("      Match failed.")
                End If
            Next
            Console.WriteLine()
        End Sub
    End Module
    ' The example displays the following output:
    '       Input: aaaaa
    '          Pattern: ((?>a+))\w
    '             Match failed.
    '       Input: aaaaab
    '          Pattern: ((?>a+))\w
    '             Match: aaaaab
    '             Group 1: aaaaa
    

    Další informace o atomických skupinách naleznete v tématu Seskupování konstruktorů.

  • Porovnávání zprava doleva, které je určeno zadáním RegexOptions.RightToLeft možnosti konstruktoru Regex třídy nebo metody porovnávání statických instancí. Tato funkce je užitečná při hledání zprava doleva místo zleva doprava nebo v případech, kdy je efektivnější zahájit shodu v pravé části vzoru místo zleva. Jak ukazuje následující příklad, použití porovnávání zprava doleva může změnit chování kvantifikátorů greedy. Příklad provede dvě hledání věty, která končí číslem. Hledání zleva doprava, které používá kvantifikátor + greedy, odpovídá jedné ze šesti číslic ve větě, zatímco hledání zprava doleva odpovídá všem šesti číslicům. Popis vzoru regulárního výrazu najdete v příkladu, který znázorňuje opožděné kvantifikátory dříve v této části.

    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
        public static void Main()
        {
            string greedyPattern = @".+(\d+)\.";
            string input = "This sentence ends with the number 107325.";
            Match match;
    
            // Match from left-to-right using lazy quantifier .+?.
            match = Regex.Match(input, greedyPattern);
            if (match.Success)
                Console.WriteLine("Number at end of sentence (left-to-right): {0}",
                                  match.Groups[1].Value);
            else
                Console.WriteLine("{0} finds no match.", greedyPattern);
    
            // Match from right-to-left using greedy quantifier .+.
            match = Regex.Match(input, greedyPattern, RegexOptions.RightToLeft);
            if (match.Success)
                Console.WriteLine("Number at end of sentence (right-to-left): {0}",
                                  match.Groups[1].Value);
            else
                Console.WriteLine("{0} finds no match.", greedyPattern);
        }
    }
    // The example displays the following output:
    //       Number at end of sentence (left-to-right): 5
    //       Number at end of sentence (right-to-left): 107325
    
    Imports System.Text.RegularExpressions
    
    Module Example
        Public Sub Main()
            Dim greedyPattern As String = ".+(\d+)\."
            Dim input As String = "This sentence ends with the number 107325."
            Dim match As Match
    
            ' Match from left-to-right using lazy quantifier .+?.
            match = Regex.Match(input, greedyPattern)
            If match.Success Then
                Console.WriteLine("Number at end of sentence (left-to-right): {0}",
                                  match.Groups(1).Value)
            Else
                Console.WriteLine("{0} finds no match.", greedyPattern)
            End If
    
            ' Match from right-to-left using greedy quantifier .+.
            match = Regex.Match(input, greedyPattern, RegexOptions.RightToLeft)
            If match.Success Then
                Console.WriteLine("Number at end of sentence (right-to-left): {0}",
                                  match.Groups(1).Value)
            Else
                Console.WriteLine("{0} finds no match.", greedyPattern)
            End If
        End Sub
    End Module
    ' The example displays the following output:
    '       Number at end of sentence (left-to-right): 5
    '       Number at end of sentence (right-to-left): 107325
    

    Další informace o porovnávání zprava doleva naleznete v tématu Možnosti regulárního výrazu.

  • Pozitivní a negativní vzhled: (?<=dílčí výraz) pro pozitivní vzhled, a (?<!dílčí výraz) pro negativní vzhled. Tato funkce se podobá vyhledávání, které je popsáno dříve v tomto tématu. Vzhledem k tomu, že modul regulárních výrazů umožňuje úplné porovnávání zprava doleva, regulární výrazy umožňují neomezené vyhledávání. Pozitivní a negativní vzhled lze použít také k zabránění vnoření kvantifikátorů, pokud je vnořený dílčí výraz nadmnožinou vnějšího výrazu. Regulární výrazy s těmito vnořenými kvantifikátory často nabízejí nízký výkon. Následující příklad například ověří, že řetězec začíná a končí alfanumerickým znakem a že jakýkoli jiný znak v řetězci je jedním z větší podmnožina. Tvoří část regulárního výrazu použitého k ověření e-mailových adres; Další informace naleznete v tématu Postupy: Ověření, zda řetězce jsou v platném formátu e-mailu.

    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
        public static void Main()
        {
            string[] inputs = { "jack.sprat", "dog#", "dog#1", "me.myself",
                              "me.myself!" };
            string pattern = @"^[A-Z0-9]([-!#$%&'.*+/=?^`{}|~\w])*(?<=[A-Z0-9])$";
            foreach (string input in inputs)
            {
                if (Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase))
                    Console.WriteLine("{0}: Valid", input);
                else
                    Console.WriteLine("{0}: Invalid", input);
            }
        }
    }
    // The example displays the following output:
    //       jack.sprat: Valid
    //       dog#: Invalid
    //       dog#1: Valid
    //       me.myself: Valid
    //       me.myself!: Invalid
    
    Imports System.Text.RegularExpressions
    
    Module Example
        Public Sub Main()
            Dim inputs() As String = {"jack.sprat", "dog#", "dog#1", "me.myself",
                                       "me.myself!"}
            Dim pattern As String = "^[A-Z0-9]([-!#$%&'.*+/=?^`{}|~\w])*(?<=[A-Z0-9])$"
            For Each input As String In inputs
                If Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase) Then
                    Console.WriteLine("{0}: Valid", input)
                Else
                    Console.WriteLine("{0}: Invalid", input)
                End If
            Next
        End Sub
    End Module
    ' The example displays the following output:
    '       jack.sprat: Valid
    '       dog#: Invalid
    '       dog#1: Valid
    '       me.myself: Valid
    '       me.myself!: Invalid
    

    Regulární výraz ^[A-Z0-9]([-!#$%&'.*+/=?^`{}|~\w])*(?<=[A-Z0-9])$ je definován, jak je znázorněno v následující tabulce.

    Vzor Popis
    ^ Zahajte shodu na začátku řetězce.
    [A-Z0-9] Porovná libovolný číselný nebo alfanumerický znak. (Porovnání nerozlišuje malá a velká písmena.)
    ([-!#$%&'.*+/=?^`{}|~\w])* Porovná žádný nebo více výskytů libovolného znaku slova nebo některého z následujících znaků: -, !, #, $, %, &, ', ., *, +, /, =, ?, ^, ', {, }, |nebo ~.
    (?<=[A-Z0-9]) Podívejte se na předchozí znak, který musí být číselný nebo alfanumerický. (Porovnání nerozlišuje malá a velká písmena.)
    $ Ukončete shodu na konci řetězce.

    Další informace o pozitivním a negativním vzhledu naleznete v tématu Seskupování konstruktorů.

Titulek Popis
Zpětné navracení Poskytuje informace o tom, jak regulární výraz vrací větve pro vyhledání alternativních shod.
Kompilace a opětovné používání Poskytuje informace o kompilaci a opakovaném opakovaném spouštění regulárních výrazů za účelem zvýšení výkonu.
Bezpečnost vlákna Poskytuje informace o bezpečnosti vláken regulárních výrazů a vysvětluje, kdy byste měli synchronizovat přístup k objektům regulárních výrazů.
Regulární výrazy .NET Poskytuje přehled aspektu programovacího jazyka regulárních výrazů.
Model objektu regulárního výrazu Poskytuje informace a příklady kódu ilustrující použití tříd regulárních výrazů.
Jazyk regulárních výrazů – stručná referenční dokumentace Poskytuje informace o sadě znaků, operátorů a konstruktorů, které můžete použít k definování regulárních výrazů.

Reference