Sdílet prostřednictvím


Možnosti regulárních výrazů

Ve výchozím nastavení je porovnání vstupního řetězce s libovolnými literálními znaky v vzoru regulárního výrazu citlivé na malá a velká písmena, prázdné znaky regulárního výrazu se interpretují jako literální prázdné znaky a zachytávání skupin v regulárním výrazu se pojmenovávají implicitně i explicitně. Tyto a několik dalších aspektů výchozího chování regulárních výrazů můžete upravit zadáním možností regulárního výrazu. Některé z těchto možností, které jsou uvedeny v následující tabulce, mohou být začleněny přímo jako součást vzoru regulárního výrazu, nebo je lze zadat do konstruktoru System.Text.RegularExpressions.Regex třídy nebo statické metody pro porovnání vzorů jako výčtovou hodnotu System.Text.RegularExpressions.RegexOptions.

RegexOptions člen Vložený znak Účinnost Více informací
None Není k dispozici Použijte výchozí chování. Výchozí možnosti
IgnoreCase i Použije porovnávání, které nerozlišuje velká a malá písmena. Porovnávání nerozlišující malá a velká písmena
Multiline m Použijte víceřádkový režim, kde ^ a $ označuje začátek a konec každého řádku (místo začátku a konce vstupního řetězce). Víceřádkový režim
Singleline s Použijte režim s jedním řádkem, kde tečka (.) odpovídá každému znaku (místo každého znaku kromě \n). Režim s jedním řádkem
ExplicitCapture n Nezachycujte nepojmenované skupiny. Jediná platná zachycení jsou explicitně pojmenované nebo očíslované skupiny ve formě (?<název>dílčí výrazy). Pouze explicitní zachycení
Compiled Není k dispozici Zkompilujte regulární výraz do sestavení. Kompilované regulární výrazy
IgnorePatternWhitespace x Vyloučíte z vzoru nepoupravené prázdné znaky a povolíte komentáře za znaménkem čísla (#). Ignorovat prázdné znaky
RightToLeft Není k dispozici Změňte směr hledání. Hledání se přesune zprava doleva místo zleva doprava. Režim zprava doleva
ECMAScript Není k dispozici Povolte pro výraz chování kompatibilní s ECMAScriptem. Chování shodování ECMAScriptu
CultureInvariant Není k dispozici Ignorujte kulturní rozdíly v jazyce. Porovnání pomocí invariantní jazykové verze
NonBacktracking Není k dispozici Porovnávání pomocí přístupu, který zabraňuje navracení a zaručuje lineární zpracování času v délce vstupu. (K dispozici v .NET 7 a novějších verzích.) Režim bez zpětného sledování

Zadání možností

Možnosti regulárních výrazů můžete zadat jedním ze tří způsobů:

  • V parametru options konstruktoru třídy System.Text.RegularExpressions.Regex nebo statické metody pro porovnávání vzorů (Shared v jazyce Visual Basic), například Regex(String, RegexOptions) nebo Regex.Match(String, String, RegexOptions). Parametr options je bitová OR kombinace hodnoty výčtového System.Text.RegularExpressions.RegexOptions typu.

    Při zadání možností do Regex instance pomocí options parametru konstruktoru třídy jsou možnosti přiřazeny k System.Text.RegularExpressions.RegexOptions vlastnosti. System.Text.RegularExpressions.RegexOptions však vlastnost neodráží přímé možnosti v samotném vzoru regulárního výrazu.

    V následujícím příkladu je uvedena ukázka. Používá parametr options metody Regex.Match(String, String, RegexOptions) k povolení nerozlišování malých a velkých písmen a ignorování mezer ve vzoru při identifikaci slov začínajících písmenem "d".

    string pattern = @"d \w+ \s";
    string input = "Dogs are decidedly good pets.";
    RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace;
    
    foreach (Match match in Regex.Matches(input, pattern, options))
        Console.WriteLine($"'{match.Value}// found at index {match.Index}.");
    // The example displays the following output:
    //    'Dogs // found at index 0.
    //    'decidedly // found at index 9.
    
    Dim pattern As String = "d \w+ \s"
    Dim input As String = "Dogs are decidedly good pets."
    Dim options As RegexOptions = RegexOptions.IgnoreCase Or RegexOptions.IgnorePatternWhitespace
    
    For Each match As Match In Regex.Matches(input, pattern, options)
        Console.WriteLine("'{0}' found at index {1}.", match.Value, match.Index)
    Next
    ' The example displays the following output:
    '    'Dogs ' found at index 0.
    '    'decidedly ' found at index 9.      
    
  • Použitím vložených možností v vzoru regulárního výrazu se syntaxí (?imnsx-imnsx). Možnost se vztahuje na vzor od místa, kde je definována, až buď do konce vzoru, nebo do místa, kde je jinou vloženou možností zneplatněna. Všimněte si, že System.Text.RegularExpressions.RegexOptions vlastnost Regex instance neodráží tyto vložené možnosti. Další informace naleznete v tématu Různé konstrukce .

    V následujícím příkladu je uvedena ukázka. Používá vložené možnosti k povolení porovnávání bez rozlišování velkých a malých písmen a ignorování bílé mezery při identifikaci slov začínajících písmenem "d".

    string pattern = @"(?ix) d \w+ \s";
    string input = "Dogs are decidedly good pets.";
    
    foreach (Match match in Regex.Matches(input, pattern))
        Console.WriteLine($"'{match.Value}// found at index {match.Index}.");
    // The example displays the following output:
    //    'Dogs // found at index 0.
    //    'decidedly // found at index 9.
    
    Dim pattern As String = "\b(?ix) d \w+ \s"
    Dim input As String = "Dogs are decidedly good pets."
    
    For Each match As Match In Regex.Matches(input, pattern)
        Console.WriteLine("'{0}' found at index {1}.", match.Value, match.Index)
    Next
    ' The example displays the following output:
    '    'Dogs ' found at index 0.
    '    'decidedly ' found at index 9.      
    
  • Použitím vložených možností v konkrétním konstruktoru seskupení ve vzoru regulárního výrazu se syntaxí (?imnsx-imnsx:dílčího výrazu). Žádné znaménko před sadou možností ji zapne; znaménko minus před sadou možností ji vypne. (? je pevná část syntaxe konstruktoru jazyka, která se vyžaduje, jestli jsou možnosti povolené nebo zakázané.) Tato možnost se vztahuje pouze na tuto skupinu. Další informace naleznete v tématu Seskupování konstruktů.

    V následujícím příkladu je uvedena ukázka. Používá vložené možnosti v konstruktu seskupování k povolení rozlišování mezi velkými a malými písmeny a ignorování mezer ve vzoru při identifikaci slov začínajících písmenem "d".

    string pattern = @"\b(?ix: d \w+)\s";
    string input = "Dogs are decidedly good pets.";
    
    foreach (Match match in Regex.Matches(input, pattern))
        Console.WriteLine($"'{match.Value}// found at index {match.Index}.");
    // The example displays the following output:
    //    'Dogs // found at index 0.
    //    'decidedly // found at index 9.
    
    Dim pattern As String = "\b(?ix: d \w+)\s"
    Dim input As String = "Dogs are decidedly good pets."
    
    For Each match As Match In Regex.Matches(input, pattern)
        Console.WriteLine("'{0}' found at index {1}.", match.Value, match.Index)
    Next
    ' The example displays the following output:
    '    'Dogs ' found at index 0.
    '    'decidedly ' found at index 9.      
    

Pokud jsou možnosti zadány v řádku, znaménko minus (-) před možností nebo sada možností tyto možnosti vypne. Například vložený konstruktor (?ix-ms) zapne možnosti RegexOptions.IgnoreCase a RegexOptions.IgnorePatternWhitespace a vypne možnosti RegexOptions.Multiline a RegexOptions.Singleline. Všechny možnosti regulárních výrazů jsou ve výchozím nastavení vypnuté.

Poznámka:

Pokud možnosti regulárního výrazu options zadané v parametru konstruktoru nebo volání metody kolidují s možnostmi zadanými v vzoru regulárního výrazu, použijí se vložené možnosti.

Následujících pět možností regulárních výrazů lze nastavit jak s parametrem možností, tak přímo v textu.

Následující pět možností regulárního výrazu lze nastavit pomocí parametru options , ale nelze je nastavit jako vložený:

Určení možností

Můžete určit, které možnosti byly poskytnuty objektu Regex při jeho instancování, získáním hodnoty jen pro čtení vlastnosti Regex.Options.

Provedete-li operaci AND s hodnotou vlastnosti Regex.Options a hodnotou RegexOptions, můžete otestovat přítomnost jakékoli možnosti kromě RegexOptions.None. Potom otestujte, jestli se výsledek rovná této RegexOptions hodnotě. Následující příklad testuje, zda byla nastavena možnost RegexOptions.IgnoreCase.

if ((rgx.Options & RegexOptions.IgnoreCase) == RegexOptions.IgnoreCase)
    Console.WriteLine("Case-insensitive pattern comparison.");
else
    Console.WriteLine("Case-sensitive pattern comparison.");
If (rgx.Options And RegexOptions.IgnoreCase) = RegexOptions.IgnoreCase Then
    Console.WriteLine("Case-insensitive pattern comparison.")
Else
    Console.WriteLine("Case-sensitive pattern comparison.")
End If

Chcete-li testovat RegexOptions.None, určete, zda hodnota Regex.Options vlastnosti je rovna RegexOptions.None, jak ukazuje následující příklad.

if (rgx.Options == RegexOptions.None)
    Console.WriteLine("No options have been set.");
If rgx.Options = RegexOptions.None Then
    Console.WriteLine("No options have been set.")
End If

Následující části obsahují seznam možností podporovaných regulárním výrazem v .NET.

Výchozí možnosti

Tato RegexOptions.None možnost označuje, že nebyly zadány žádné možnosti a modul regulárních výrazů používá výchozí chování. To zahrnuje následující:

  • Vzor se interpretuje jako kanonický místo regulárního výrazu ECMAScript.

  • Vzor regulárního výrazu se shoduje se vstupním řetězcem zleva doprava.

  • Porovnání rozlišují malá a velká písmena.

  • Jazykové prvky ^ a $ označují začátek a konec vstupního řetězce. Konec vstupního řetězce může být koncový znak nového řádku \n.

  • Element . jazyka odpovídá každému znaku s výjimkou \n.

  • Jakékoli prázdné znaky ve vzoru regulárního výrazu se interpretují jako doslovný znak mezery.

  • Zvyklosti aktuální kultury se používají při porovnávání vzoru se vstupním řetězcem.

  • Zachytávání skupin v vzoru regulárního výrazu je implicitní i explicitní.

Poznámka:

Možnost RegexOptions.None nemá žádný vložený ekvivalent. Pokud jsou možnosti regulárního výrazu použity přímo v textu, výchozí chování se obnoví na základě jednotlivých možností vypnutím určité možnosti. Například (?i) zapne porovnávání bez rozlišování velikosti písmen, a (?-i) obnoví výchozí porovnání, které rozlišuje velká a malá písmena.

Vzhledem k tomu, že RegexOptions.None možnost představuje výchozí chování modulu regulárních výrazů, je zřídka explicitně určena ve volání metody. Místo toho se volá konstruktor nebo statická metoda porovnávání vzorů bez parametru options .

Porovnávání, kde nezáleží na velikosti písmen

Možnost IgnoreCase nebo vložená i možnost poskytuje porovnávání bez rozlišování malých a velkých písmen. Ve výchozím nastavení se použijí konvence pro velikost písmen aktuální kultury.

Následující příklad definuje vzor regulárního výrazu, \bthe\w*\bkterý odpovídá všem slovům začínajícím na "the". Protože první volání metody Match používá výchozí porovnání s rozlišováním velkých a malých písmen, výstup naznačuje, že slovo "The", které začíná větou, neodpovídá. Je shodován při Match zavolání metody s možnostmi nastavenými na IgnoreCase.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\bthe\w*\b";
      string input = "The man then told them about that event.";
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine($"Found {match.Value} at index {match.Index}.");

      Console.WriteLine();
      foreach (Match match in Regex.Matches(input, pattern,
                                            RegexOptions.IgnoreCase))
         Console.WriteLine($"Found {match.Value} at index {match.Index}.");
   }
}
// The example displays the following output:
//       Found then at index 8.
//       Found them at index 18.
//
//       Found The at index 0.
//       Found then at index 8.
//       Found them at index 18.
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "\bthe\w*\b"
        Dim input As String = "The man then told them about that event."
        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine("Found {0} at index {1}.", match.Value, match.Index)
        Next
        Console.WriteLine()
        For Each match As Match In Regex.Matches(input, pattern, _
                                                 RegexOptions.IgnoreCase)
            Console.WriteLine("Found {0} at index {1}.", match.Value, match.Index)
        Next
    End Sub
End Module
' The example displays the following output:
'       Found then at index 8.
'       Found them at index 18.
'       
'       Found The at index 0.
'       Found then at index 8.
'       Found them at index 18.

Následující příklad upravuje vzor regulárního výrazu z předchozího příkladu tak, že místo parametru options využívá vložené možnosti pro zajištění porovnání bez rozlišování malých a velkých písmen. První vzor definuje možnost nerozlišující velká a malá písmena v konstruktoru seskupení, která se vztahuje pouze na písmeno "t" v řetězci "the". Vzhledem k tomu, že se konstruktor možnosti vyskytuje na začátku vzoru, druhý vzor použije možnost nerozlišující velká a malá písmena na celý regulární výraz.

using System;
using System.Text.RegularExpressions;

public class CaseExample
{
    public static void Main()
    {
        string pattern = @"\b(?i:t)he\w*\b";
        string input = "The man then told them about that event.";
        foreach (Match match in Regex.Matches(input, pattern))
            Console.WriteLine($"Found {match.Value} at index {match.Index}.");

        Console.WriteLine();
        pattern = @"(?i)\bthe\w*\b";
        foreach (Match match in Regex.Matches(input, pattern,
                                              RegexOptions.IgnoreCase))
            Console.WriteLine($"Found {match.Value} at index {match.Index}.");
    }
}
// The example displays the following output:
//       Found The at index 0.
//       Found then at index 8.
//       Found them at index 18.
//
//       Found The at index 0.
//       Found then at index 8.
//       Found them at index 18.
Imports System.Text.RegularExpressions

Module CaseExample
    Public Sub Main()
        Dim pattern As String = "\b(?i:t)he\w*\b"
        Dim input As String = "The man then told them about that event."
        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine("Found {0} at index {1}.", match.Value, match.Index)
        Next
        Console.WriteLine()
        pattern = "(?i)\bthe\w*\b"
        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine("Found {0} at index {1}.", match.Value, match.Index)
        Next
    End Sub
End Module

' The example displays the following output:
'       Found The at index 0.
'       Found then at index 8.
'       Found them at index 18.
'       
'       Found The at index 0.
'       Found then at index 8.
'       Found them at index 18.

Víceřádkový režim

Možnost RegexOptions.Multiline nebo vložená m možnost umožňuje modulu regulárních výrazů zpracovat vstupní řetězec, který se skládá z více řádků. Změní interpretaci elementů ^ a $ jazyka tak, aby označily začátek a konec řádku místo začátku a konce vstupního řetězce.

Ve výchozím nastavení bude $ splněna pouze na konci vstupního řetězce. Pokud zadáte možnost RegexOptions.Multiline, bude to splněno buď znakem nového řádku (\n), nebo koncem vstupního řetězce.

V žádném případě nerozpozná $ kombinaci znaků návratu a posunu řádku (\r\n). $ vždy ignoruje všechny návratové znaky (\r). Chcete-li ukončit shodu buď \r\n nebo \n, použijte dílčí výraz \r?$ nikoliv pouze $. Všimněte si, že se tím \r stane součástí shody.

Následující příklad extrahuje jména nadhazovačů a jejich skóre a přidá je do kolekce SortedList<TKey,TValue>, která je seřadí v sestupném pořadí. Metoda Matches se volá dvakrát. Při prvním volání metody je ^(\w+)\s(\d+)$ regulární výraz a nejsou nastaveny žádné možnosti. Jak ukazuje výstup, protože modul regulárních výrazů nemůže odpovídat vstupnímu vzoru spolu se začátkem a koncem vstupního řetězce, nebyly nalezeny žádné shody. Ve druhém volání metody se regulární výraz změní na ^(\w+)\s(\d+)\r?$ a možnosti jsou nastaveny na RegexOptions.Multiline. Jak ukazuje výstup, názvy a skóre se úspěšně shodují a skóre se zobrazí v sestupném pořadí.

using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

public class Multiline1Example
{
    public static void Main()
    {
        SortedList<int, string> scores = new SortedList<int, string>(new DescendingComparer1<int>());

        string input = "Joe 164\n" +
                       "Sam 208\n" +
                       "Allison 211\n" +
                       "Gwen 171\n";
        string pattern = @"^(\w+)\s(\d+)$";
        bool matched = false;

        Console.WriteLine("Without Multiline option:");
        foreach (Match match in Regex.Matches(input, pattern))
        {
            scores.Add(Int32.Parse(match.Groups[2].Value), (string)match.Groups[1].Value);
            matched = true;
        }
        if (!matched)
            Console.WriteLine("   No matches.");
        Console.WriteLine();

        // Redefine pattern to handle multiple lines.
        pattern = @"^(\w+)\s(\d+)\r*$";
        Console.WriteLine("With multiline option:");
        foreach (Match match in Regex.Matches(input, pattern, RegexOptions.Multiline))
            scores.Add(Int32.Parse(match.Groups[2].Value), (string)match.Groups[1].Value);

        // List scores in descending order.
        foreach (KeyValuePair<int, string> score in scores)
            Console.WriteLine($"{score.Value}: {score.Key}");
    }
}

public class DescendingComparer1<T> : IComparer<T>
{
    public int Compare(T x, T y)
    {
        return Comparer<T>.Default.Compare(x, y) * -1;
    }
}
// The example displays the following output:
//   Without Multiline option:
//      No matches.
//
//   With multiline option:
//   Allison: 211
//   Sam: 208
//   Gwen: 171
//   Joe: 164
Imports System.Collections.Generic
Imports System.Text.RegularExpressions

Module Multiline1Example
    Public Sub Main()
        Dim scores As New SortedList(Of Integer, String)(New DescendingComparer1(Of Integer)())

        Dim input As String = "Joe 164" + vbCrLf +
                              "Sam 208" + vbCrLf +
                              "Allison 211" + vbCrLf +
                              "Gwen 171" + vbCrLf
        Dim pattern As String = "^(\w+)\s(\d+)$"
        Dim matched As Boolean = False

        Console.WriteLine("Without Multiline option:")
        For Each match As Match In Regex.Matches(input, pattern)
            scores.Add(CInt(match.Groups(2).Value), match.Groups(1).Value)
            matched = True
        Next
        If Not matched Then Console.WriteLine("   No matches.")
        Console.WriteLine()

        ' Redefine pattern to handle multiple lines.
        pattern = "^(\w+)\s(\d+)\r*$"
        Console.WriteLine("With multiline option:")
        For Each match As Match In Regex.Matches(input, pattern, RegexOptions.Multiline)
            scores.Add(CInt(match.Groups(2).Value), match.Groups(1).Value)
        Next
        ' List scores in descending order. 
        For Each score As KeyValuePair(Of Integer, String) In scores
            Console.WriteLine("{0}: {1}", score.Value, score.Key)
        Next
    End Sub
End Module

Public Class DescendingComparer1(Of T) : Implements IComparer(Of T)
    Public Function Compare(x As T, y As T) As Integer _
           Implements IComparer(Of T).Compare
        Return Comparer(Of T).Default.Compare(x, y) * -1
    End Function
End Class
' The example displays the following output:
'    Without Multiline option:
'       No matches.
'    
'    With multiline option:
'    Allison: 211
'    Sam: 208
'    Gwen: 171
'    Joe: 164

Vzor regulárního výrazu ^(\w+)\s(\d+)\r*$ je definován, jak je znázorněno v následující tabulce.

Vzor Popis
^ Začněte na začátku řádku.
(\w+) Porovná jeden nebo více znaků tvořících slovo. Toto je první zachytávající skupina.
\s Porovná prázdný znak.
(\d+) Porovná jednu nebo více desítkových číslic. Toto je druhá zachytávající skupina.
\r? Vyhovuje nula nebo jeden znak návratu vozíku.
$ Končí na konci řádku.

Následující příklad je ekvivalentní předchozímu, s tím rozdílem, že používá vloženou možnost (?m) k nastavení víceřádkové možnosti.

using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

public class Multiline2Example
{
    public static void Main()
    {
        SortedList<int, string> scores = new SortedList<int, string>(new DescendingComparer<int>());

        string input = "Joe 164\n" +
                       "Sam 208\n" +
                       "Allison 211\n" +
                       "Gwen 171\n";
        string pattern = @"(?m)^(\w+)\s(\d+)\r*$";

        foreach (Match match in Regex.Matches(input, pattern, RegexOptions.Multiline))
            scores.Add(Convert.ToInt32(match.Groups[2].Value), match.Groups[1].Value);

        // List scores in descending order.
        foreach (KeyValuePair<int, string> score in scores)
            Console.WriteLine($"{score.Value}: {score.Key}");
    }
}

public class DescendingComparer<T> : IComparer<T>
{
    public int Compare(T x, T y)
    {
        return Comparer<T>.Default.Compare(x, y) * -1;
    }
}
// The example displays the following output:
//    Allison: 211
//    Sam: 208
//    Gwen: 171
//    Joe: 164
Imports System.Collections.Generic
Imports System.Text.RegularExpressions

Module Multiline2Example
    Public Sub Main()
        Dim scores As New SortedList(Of Integer, String)(New DescendingComparer(Of Integer)())

        Dim input As String = "Joe 164" + vbCrLf +
                              "Sam 208" + vbCrLf +
                              "Allison 211" + vbCrLf +
                              "Gwen 171" + vbCrLf
        Dim pattern As String = "(?m)^(\w+)\s(\d+)\r*$"

        For Each match As Match In Regex.Matches(input, pattern, RegexOptions.Multiline)
            scores.Add(CInt(match.Groups(2).Value), match.Groups(1).Value)
        Next
        ' List scores in descending order. 
        For Each score As KeyValuePair(Of Integer, String) In scores
            Console.WriteLine("{0}: {1}", score.Value, score.Key)
        Next
    End Sub
End Module

Public Class DescendingComparer(Of T) : Implements IComparer(Of T)
    Public Function Compare(x As T, y As T) As Integer _
           Implements IComparer(Of T).Compare
        Return Comparer(Of T).Default.Compare(x, y) * -1
    End Function
End Class
' The example displays the following output:
'    Allison: 211
'    Sam: 208
'    Gwen: 171
'    Joe: 164

Režim s jedním řádkem

Možnost RegexOptions.Singleline nebo vložená možnost s způsobí, že mechanismus regulárních výrazů zachází se vstupním řetězcem, jako by byl považován za jeden řádek. Dělá to změnou chování jazykového prvku tečky (.) tak, aby odpovídal každému znaku, místo aby odpovídal každému znaku s výjimkou znaku nového řádku \n.

Následující příklad ukazuje, jak se chování . elementu jazyka změní při použití RegexOptions.Singleline možnosti. Regulární výraz ^.+ začíná na začátku řetězce a odpovídá každému znaku. Ve výchozím nastavení končí shoda na konci prvního řádku; vzor regulárního výrazu odpovídá znaku návratu vozíku \r, ale neshoduje se s \n. Vzhledem k tomu, že RegexOptions.Singleline možnost interpretuje celý vstupní řetězec jako jeden řádek, odpovídá každému znaku ve vstupním řetězci, včetně \n.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = "^.+";
      string input = "This is one line and" + Environment.NewLine + "this is the second.";
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine(Regex.Escape(match.Value));

      Console.WriteLine();
      foreach (Match match in Regex.Matches(input, pattern, RegexOptions.Singleline))
         Console.WriteLine(Regex.Escape(match.Value));
   }
}
// The example displays the following output:
//       This\ is\ one\ line\ and\r
//
//       This\ is\ one\ line\ and\r\nthis\ is\ the\ second\.
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "^.+"
        Dim input As String = "This is one line and" + vbCrLf + "this is the second."
        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine(Regex.Escape(match.Value))
        Next
        Console.WriteLine()
        For Each match As Match In Regex.Matches(input, pattern, RegexOptions.SingleLine)
            Console.WriteLine(Regex.Escape(match.Value))
        Next
    End Sub
End Module
' The example displays the following output:
'       This\ is\ one\ line\ and\r
'       
'       This\ is\ one\ line\ and\r\nthis\ is\ the\ second\.

Následující příklad je ekvivalentní předchozímu, s tím rozdílem, že používá vloženou možnost (?s) k povolení jednořádkového režimu.

using System;
using System.Text.RegularExpressions;

public class SingleLineExample
{
    public static void Main()
    {
        string pattern = "(?s)^.+";
        string input = "This is one line and" + Environment.NewLine + "this is the second.";

        foreach (Match match in Regex.Matches(input, pattern))
            Console.WriteLine(Regex.Escape(match.Value));
    }
}
// The example displays the following output:
//       This\ is\ one\ line\ and\r\nthis\ is\ the\ second\.
Imports System.Text.RegularExpressions

Module SingleLineExample
    Public Sub Main()
        Dim pattern As String = "(?s)^.+"
        Dim input As String = "This is one line and" + vbCrLf + "this is the second."

        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine(Regex.Escape(match.Value))
        Next
    End Sub
End Module
' The example displays the following output:
'       This\ is\ one\ line\ and\r\nthis\ is\ the\ second\.

Pouze explicitní zachycení

Ve výchozím nastavení jsou zachytávací skupiny definovány pomocí závorek ve vzoru regulárního výrazu. Pojmenované skupiny mají přiřazený název nebo číslo podle možností jazyka názvupodvýrazu, zatímco nepojmenované skupiny jsou přístupné pomocí indexu. V objektu GroupCollection jsou nepojmenované skupiny před pojmenovanými skupinami.

Konstrukty seskupení se často používají pouze k tomu, aby se kvantifikátory aplikovaly na více prvků jazyka, a zachycené podřetězce nejsou zajímavé. Pokud například následující regulární výraz:

\b\(?((\w+),?\s?)+[\.!?]\)?

je určen pouze k extrakci vět z dokumentu, které končí tečkou, vykřičníkem nebo otazníkem, zajímavá je pouze výsledná věta (která je reprezentována objektem Match). Jednotlivá slova v kolekci nejsou přítomna.

Zachytávání skupin, které se následně nepoužívají, může být nákladné, protože modul regulárních výrazů musí vytvořit obsah jak pro GroupCollection, tak i pro CaptureCollection. Jako alternativu můžete buď použít možnost RegexOptions.ExplicitCapture, nebo vloženou možnost n k určení, že jediné platné zachycení jsou explicitně pojmenované nebo očíslované skupiny, které jsou určeny konstruktem (?<názvu>podvýrazu).

Následující příklad zobrazuje informace o shodách vrácených vzorem regulárního výrazu \b\(?((\w+),?\s?)+[\.!?]\)?, když je tato metoda Match volána s možností RegexOptions.ExplicitCapture a bez ní. Jak ukazuje výstup z prvního volání metody, modul regulárních výrazů plně naplní GroupCollection objekty a CaptureCollection kolekce informacemi o zachycených podřetězcích. Protože je druhá metoda volána s options nastavenou na RegexOptions.ExplicitCapture, nezachytává informace o skupinách.

using System;
using System.Text.RegularExpressions;

public class Explicit1Example
{
    public static void Main()
    {
        string input = "This is the first sentence. Is it the beginning " +
                       "of a literary masterpiece? I think not. Instead, " +
                       "it is a nonsensical paragraph.";
        string pattern = @"\b\(?((?>\w+),?\s?)+[\.!?]\)?";
        Console.WriteLine("With implicit captures:");
        foreach (Match match in Regex.Matches(input, pattern))
        {
            Console.WriteLine($"The match: {match.Value}");
            int groupCtr = 0;
            foreach (Group group in match.Groups)
            {
                Console.WriteLine($"   Group {groupCtr}: {group.Value}");
                groupCtr++;
                int captureCtr = 0;
                foreach (Capture capture in group.Captures)
                {
                    Console.WriteLine($"      Capture {captureCtr}: {capture.Value}");
                    captureCtr++;
                }
            }
        }
        Console.WriteLine();
        Console.WriteLine("With explicit captures only:");
        foreach (Match match in Regex.Matches(input, pattern, RegexOptions.ExplicitCapture))
        {
            Console.WriteLine($"The match: {match.Value}");
            int groupCtr = 0;
            foreach (Group group in match.Groups)
            {
                Console.WriteLine($"   Group {groupCtr}: {group.Value}");
                groupCtr++;
                int captureCtr = 0;
                foreach (Capture capture in group.Captures)
                {
                    Console.WriteLine($"      Capture {captureCtr}: {capture.Value}");
                    captureCtr++;
                }
            }
        }
    }
}
// The example displays the following output:
//    With implicit captures:
//    The match: This is the first sentence.
//       Group 0: This is the first sentence.
//          Capture 0: This is the first sentence.
//       Group 1: sentence
//          Capture 0: This
//          Capture 1: is
//          Capture 2: the
//          Capture 3: first
//          Capture 4: sentence
//       Group 2: sentence
//          Capture 0: This
//          Capture 1: is
//          Capture 2: the
//          Capture 3: first
//          Capture 4: sentence
//    The match: Is it the beginning of a literary masterpiece?
//       Group 0: Is it the beginning of a literary masterpiece?
//          Capture 0: Is it the beginning of a literary masterpiece?
//       Group 1: masterpiece
//          Capture 0: Is
//          Capture 1: it
//          Capture 2: the
//          Capture 3: beginning
//          Capture 4: of
//          Capture 5: a
//          Capture 6: literary
//          Capture 7: masterpiece
//       Group 2: masterpiece
//          Capture 0: Is
//          Capture 1: it
//          Capture 2: the
//          Capture 3: beginning
//          Capture 4: of
//          Capture 5: a
//          Capture 6: literary
//          Capture 7: masterpiece
//    The match: I think not.
//       Group 0: I think not.
//          Capture 0: I think not.
//       Group 1: not
//          Capture 0: I
//          Capture 1: think
//          Capture 2: not
//       Group 2: not
//          Capture 0: I
//          Capture 1: think
//          Capture 2: not
//    The match: Instead, it is a nonsensical paragraph.
//       Group 0: Instead, it is a nonsensical paragraph.
//          Capture 0: Instead, it is a nonsensical paragraph.
//       Group 1: paragraph
//          Capture 0: Instead,
//          Capture 1: it
//          Capture 2: is
//          Capture 3: a
//          Capture 4: nonsensical
//          Capture 5: paragraph
//       Group 2: paragraph
//          Capture 0: Instead
//          Capture 1: it
//          Capture 2: is
//          Capture 3: a
//          Capture 4: nonsensical
//          Capture 5: paragraph
//
//    With explicit captures only:
//    The match: This is the first sentence.
//       Group 0: This is the first sentence.
//          Capture 0: This is the first sentence.
//    The match: Is it the beginning of a literary masterpiece?
//       Group 0: Is it the beginning of a literary masterpiece?
//          Capture 0: Is it the beginning of a literary masterpiece?
//    The match: I think not.
//       Group 0: I think not.
//          Capture 0: I think not.
//    The match: Instead, it is a nonsensical paragraph.
//       Group 0: Instead, it is a nonsensical paragraph.
//          Capture 0: Instead, it is a nonsensical paragraph.
Imports System.Text.RegularExpressions

Module Explicit1Example
    Public Sub Main()
        Dim input As String = "This is the first sentence. Is it the beginning " +
                              "of a literary masterpiece? I think not. Instead, " +
                              "it is a nonsensical paragraph."
        Dim pattern As String = "\b\(?((?>\w+),?\s?)+[\.!?]\)?"
        Console.WriteLine("With implicit captures:")
        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine("The match: {0}", match.Value)
            Dim groupCtr As Integer = 0
            For Each group As Group In match.Groups
                Console.WriteLine("   Group {0}: {1}", groupCtr, group.Value)
                groupCtr += 1
                Dim captureCtr As Integer = 0
                For Each capture As Capture In group.Captures
                    Console.WriteLine("      Capture {0}: {1}", captureCtr, capture.Value)
                    captureCtr += 1
                Next
            Next
        Next
        Console.WriteLine()
        Console.WriteLine("With explicit captures only:")
        For Each match As Match In Regex.Matches(input, pattern, RegexOptions.ExplicitCapture)
            Console.WriteLine("The match: {0}", match.Value)
            Dim groupCtr As Integer = 0
            For Each group As Group In match.Groups
                Console.WriteLine("   Group {0}: {1}", groupCtr, group.Value)
                groupCtr += 1
                Dim captureCtr As Integer = 0
                For Each capture As Capture In group.Captures
                    Console.WriteLine("      Capture {0}: {1}", captureCtr, capture.Value)
                    captureCtr += 1
                Next
            Next
        Next
    End Sub
End Module
' The example displays the following output:
'    With implicit captures:
'    The match: This is the first sentence.
'       Group 0: This is the first sentence.
'          Capture 0: This is the first sentence.
'       Group 1: sentence
'          Capture 0: This
'          Capture 1: is
'          Capture 2: the
'          Capture 3: first
'          Capture 4: sentence
'       Group 2: sentence
'          Capture 0: This
'          Capture 1: is
'          Capture 2: the
'          Capture 3: first
'          Capture 4: sentence
'    The match: Is it the beginning of a literary masterpiece?
'       Group 0: Is it the beginning of a literary masterpiece?
'          Capture 0: Is it the beginning of a literary masterpiece?
'       Group 1: masterpiece
'          Capture 0: Is
'          Capture 1: it
'          Capture 2: the
'          Capture 3: beginning
'          Capture 4: of
'          Capture 5: a
'          Capture 6: literary
'          Capture 7: masterpiece
'       Group 2: masterpiece
'          Capture 0: Is
'          Capture 1: it
'          Capture 2: the
'          Capture 3: beginning
'          Capture 4: of
'          Capture 5: a
'          Capture 6: literary
'          Capture 7: masterpiece
'    The match: I think not.
'       Group 0: I think not.
'          Capture 0: I think not.
'       Group 1: not
'          Capture 0: I
'          Capture 1: think
'          Capture 2: not
'       Group 2: not
'          Capture 0: I
'          Capture 1: think
'          Capture 2: not
'    The match: Instead, it is a nonsensical paragraph.
'       Group 0: Instead, it is a nonsensical paragraph.
'          Capture 0: Instead, it is a nonsensical paragraph.
'       Group 1: paragraph
'          Capture 0: Instead,
'          Capture 1: it
'          Capture 2: is
'          Capture 3: a
'          Capture 4: nonsensical
'          Capture 5: paragraph
'       Group 2: paragraph
'          Capture 0: Instead
'          Capture 1: it
'          Capture 2: is
'          Capture 3: a
'          Capture 4: nonsensical
'          Capture 5: paragraph
'    
'    With explicit captures only:
'    The match: This is the first sentence.
'       Group 0: This is the first sentence.
'          Capture 0: This is the first sentence.
'    The match: Is it the beginning of a literary masterpiece?
'       Group 0: Is it the beginning of a literary masterpiece?
'          Capture 0: Is it the beginning of a literary masterpiece?
'    The match: I think not.
'       Group 0: I think not.
'          Capture 0: I think not.
'    The match: Instead, it is a nonsensical paragraph.
'       Group 0: Instead, it is a nonsensical paragraph.
'          Capture 0: Instead, it is a nonsensical paragraph.

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

Vzor Popis
\b Začněte na hranici slova.
\(? Porovná žádný nebo jeden výskyt levých závorek ("(").
(?>\w+),? Porovná jeden nebo více znaků slova následovaných nulou nebo jednou čárkou. Při porovnávání znaků slova se nevracet zpět.
\s? Porovná žádný nebo jeden prázdný znak.
((\w+),?\s?)+ Porovná kombinaci jednoho nebo více znaků slova, nuly nebo jedné čárky a jednoho prázdného znaku jednou nebo vícekrát.
[\.!?]\)? Odpovídá kterémukoliv ze tří interpunkčních symbolů následovaných nulou nebo jednou pravou závorkou (")").

Můžete také použít vložený (?n) prvek k potlačení automatických zachycení. Následující příklad upraví předchozí vzor regulárního výrazu tak, aby používal vložený prvek (?n) místo prvku RegexOptions.ExplicitCapture.

using System;
using System.Text.RegularExpressions;

public class Explicit2Example
{
    public static void Main()
    {
        string input = "This is the first sentence. Is it the beginning " +
                       "of a literary masterpiece? I think not. Instead, " +
                       "it is a nonsensical paragraph.";
        string pattern = @"(?n)\b\(?((?>\w+),?\s?)+[\.!?]\)?";

        foreach (Match match in Regex.Matches(input, pattern))
        {
            Console.WriteLine($"The match: {match.Value}");
            int groupCtr = 0;
            foreach (Group group in match.Groups)
            {
                Console.WriteLine($"   Group {groupCtr}: {group.Value}");
                groupCtr++;
                int captureCtr = 0;
                foreach (Capture capture in group.Captures)
                {
                    Console.WriteLine($"      Capture {captureCtr}: {capture.Value}");
                    captureCtr++;
                }
            }
        }
    }
}
// The example displays the following output:
//       The match: This is the first sentence.
//          Group 0: This is the first sentence.
//             Capture 0: This is the first sentence.
//       The match: Is it the beginning of a literary masterpiece?
//          Group 0: Is it the beginning of a literary masterpiece?
//             Capture 0: Is it the beginning of a literary masterpiece?
//       The match: I think not.
//          Group 0: I think not.
//             Capture 0: I think not.
//       The match: Instead, it is a nonsensical paragraph.
//          Group 0: Instead, it is a nonsensical paragraph.
//             Capture 0: Instead, it is a nonsensical paragraph.
Imports System.Text.RegularExpressions

Module Explicit2Example
    Public Sub Main()
        Dim input As String = "This is the first sentence. Is it the beginning " +
                              "of a literary masterpiece? I think not. Instead, " +
                              "it is a nonsensical paragraph."
        Dim pattern As String = "(?n)\b\(?((?>\w+),?\s?)+[\.!?]\)?"

        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine("The match: {0}", match.Value)
            Dim groupCtr As Integer = 0
            For Each group As Group In match.Groups
                Console.WriteLine("   Group {0}: {1}", groupCtr, group.Value)
                groupCtr += 1
                Dim captureCtr As Integer = 0
                For Each capture As Capture In group.Captures
                    Console.WriteLine("      Capture {0}: {1}", captureCtr, capture.Value)
                    captureCtr += 1
                Next
            Next
        Next
    End Sub
End Module
' The example displays the following output:
'       The match: This is the first sentence.
'          Group 0: This is the first sentence.
'             Capture 0: This is the first sentence.
'       The match: Is it the beginning of a literary masterpiece?
'          Group 0: Is it the beginning of a literary masterpiece?
'             Capture 0: Is it the beginning of a literary masterpiece?
'       The match: I think not.
'          Group 0: I think not.
'             Capture 0: I think not.
'       The match: Instead, it is a nonsensical paragraph.
'          Group 0: Instead, it is a nonsensical paragraph.
'             Capture 0: Instead, it is a nonsensical paragraph.

Nakonec můžete pomocí vloženého prvku (?n:) skupiny potlačit automatické zachytávání podle skupin. Následující příklad upraví předchozí vzor tak, aby potlačil nepojmenované zachytávání ve vnější skupině, ((?>\w+),?\s?). Všimněte si, že to potlačí nepojmenované zachytávání také ve vnitřní skupině.

using System;
using System.Text.RegularExpressions;

public class Explicit3Example
{
    public static void Main()
    {
        string input = "This is the first sentence. Is it the beginning " +
                       "of a literary masterpiece? I think not. Instead, " +
                       "it is a nonsensical paragraph.";
        string pattern = @"\b\(?(?n:(?>\w+),?\s?)+[\.!?]\)?";

        foreach (Match match in Regex.Matches(input, pattern))
        {
            Console.WriteLine($"The match: {match.Value}");
            int groupCtr = 0;
            foreach (Group group in match.Groups)
            {
                Console.WriteLine($"   Group {groupCtr}: {group.Value}");
                groupCtr++;
                int captureCtr = 0;
                foreach (Capture capture in group.Captures)
                {
                    Console.WriteLine($"      Capture {captureCtr}: {capture.Value}");
                    captureCtr++;
                }
            }
        }
    }
}
// The example displays the following output:
//       The match: This is the first sentence.
//          Group 0: This is the first sentence.
//             Capture 0: This is the first sentence.
//       The match: Is it the beginning of a literary masterpiece?
//          Group 0: Is it the beginning of a literary masterpiece?
//             Capture 0: Is it the beginning of a literary masterpiece?
//       The match: I think not.
//          Group 0: I think not.
//             Capture 0: I think not.
//       The match: Instead, it is a nonsensical paragraph.
//          Group 0: Instead, it is a nonsensical paragraph.
//             Capture 0: Instead, it is a nonsensical paragraph.
Imports System.Text.RegularExpressions

Module Explicit3Example
    Public Sub Main()
        Dim input As String = "This is the first sentence. Is it the beginning " +
                              "of a literary masterpiece? I think not. Instead, " +
                              "it is a nonsensical paragraph."
        Dim pattern As String = "\b\(?(?n:(?>\w+),?\s?)+[\.!?]\)?"

        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine("The match: {0}", match.Value)
            Dim groupCtr As Integer = 0
            For Each group As Group In match.Groups
                Console.WriteLine("   Group {0}: {1}", groupCtr, group.Value)
                groupCtr += 1
                Dim captureCtr As Integer = 0
                For Each capture As Capture In group.Captures
                    Console.WriteLine("      Capture {0}: {1}", captureCtr, capture.Value)
                    captureCtr += 1
                Next
            Next
        Next
    End Sub
End Module
' The example displays the following output:
'       The match: This is the first sentence.
'          Group 0: This is the first sentence.
'             Capture 0: This is the first sentence.
'       The match: Is it the beginning of a literary masterpiece?
'          Group 0: Is it the beginning of a literary masterpiece?
'             Capture 0: Is it the beginning of a literary masterpiece?
'       The match: I think not.
'          Group 0: I think not.
'             Capture 0: I think not.
'       The match: Instead, it is a nonsensical paragraph.
'          Group 0: Instead, it is a nonsensical paragraph.
'             Capture 0: Instead, it is a nonsensical paragraph.

Kompilované regulární výrazy

Poznámka:

Pokud je to možné, místo kompilování regulárních výrazůRegexOptions.Compiledzdrojové generované regulární výrazy. Generování zdrojového kódu může vaší aplikaci pomoct se rychleji spustit, běžet efektivněji a být lépe optimalizovaná. Informace o tom, kdy je možné generování zdroje, najdete v tématu Kdy ji použít.

Ve výchozím nastavení se regulární výrazy v .NET interpretují. Když je vytvořena instance objektu nebo je volána statická metoda, vzor regulárního výrazu se přeloží do sady vlastních opkódů a interpret tyto opkódy používá ke spuštění regulárního výrazu. To zahrnuje kompromis: náklady na inicializaci modulu regulárních výrazů se minimalizují na úkor výkonu za běhu.

Pomocí této možnosti můžete místo interpretovaných regulárních výrazů použít kompilované výrazy RegexOptions.Compiled . V tomto případě, když je vzor předán modulu regulárních výrazů, je zanalyzován do sady operátorů a pak převeden na běžný intermediální jazyk (CIL), který lze předat přímo do Common Language Runtime (CLR). Kompilované regulární výrazy maximalizují výkon za běhu na úkor doby inicializace.

Poznámka:

Regulární výraz lze zkompilovat pouze zadáním RegexOptions.Compiled hodnoty options parametru Regex konstruktoru třídy nebo statické metody porovnávání vzorů. Není k dispozici jako vložená možnost.

Kompilované regulární výrazy můžete použít při volání statických i instancí regulárních výrazů. Ve statických regulárních výrazech je možnost RegexOptions.Compiled předána parametru options metody porovnávání vzorů regulárních výrazů. V případě regulárních výrazů je předán parametru options konstruktoru třídy Regex. V obou případech vede k lepšímu výkonu.

K tomuto zlepšení výkonu však dochází pouze za následujících podmínek:

  • Objekt Regex představující konkrétní regulární výraz se používá ve více voláních metod porovnávání vzorů regulárních výrazů.

  • Objekt Regex nemůže přejít mimo rozsah, takže ho můžete znovu použít.

  • Statický regulární výraz se používá ve více voláních metod porovnávání vzorů regulárních výrazů. (Zlepšení výkonu je možné, protože regulární výrazy používané ve volání statické metody jsou uloženy v mezipaměti modulu regulárních výrazů.)

Poznámka:

Možnost RegexOptions.Compiled nesouvisí s zastaralou Regex.CompileToAssembly metodou, která vytvoří sestavení pro zvláštní účely, které obsahuje předdefinované kompilované regulární výrazy.

Ignorovat prázdné znaky

Ve výchozím nastavení je prázdný znak ve vzoru regulárního výrazu významný; vynutí modul regulárních výrazů, aby odpovídal na prázdný znak ve vstupním řetězci. Z tohoto důvodu jsou regulární výrazy "\b\w+\s" a "\b\w+ přibližně ekvivalentní regulárním výrazům. Kromě toho, když je v vzoru regulárního výrazu zjištěn znak čísla (#), je interpretován jako literálový znak, který se má shodovat.

Možnost RegexOptions.IgnorePatternWhitespace nebo vložená x možnost změní toto výchozí chování následujícím způsobem:

  • Neoznačené mezery ve vzoru regulárního výrazu jsou ignorovány. Aby byly součástí vzoru regulárního výrazu, musí být bílé znaky escapovány (například jako \s nebo "\ ").

  • Znak čísla (#) se interpretuje jako začátek komentáře, nikoli jako literálový znak. Veškerý text v vzoru regulárního výrazu z znaku # na další \n znak nebo na konec řetězce se interpretuje jako komentář.

V následujících případech se však prázdné znaky v regulárním výrazu neignorují, i když použijete tuto možnost RegexOptions.IgnorePatternWhitespace:

  • Prázdné znaky ve třídě znaků se vždy interpretují doslova. Vzor regulárního výrazu [ .,;:] například odpovídá jakémukoli jednomu prázdnému znaku, tečkě, čárkě, středníku nebo dvojtečku.

  • Prázdné znaky nejsou povoleny v hranatém kvantifikátoru, například {n}, {n,}, a {n,m}. Například vzor \d{1, 3} regulárního výrazu neodpovídá žádné sekvenci číslic z jedné na tři číslice, protože obsahuje prázdný znak.

  • Prázdné znaky nejsou povoleny v posloupnosti znaků, která zavádí prvek jazyka. Příklad:

    • Jazykový prvek (?:dílčí výraz) představuje nesběrnou skupinu a (?: část prvku nemůže obsahovat vložené mezery. Dílčí výraz (? :subexpression) vyvolá během běhu ArgumentException, protože modul regulárních výrazů nemůže analyzovat vzor, a vzor ( ?:subexpression) se neshoduje s dílčím výrazem.

    • Jazykový element \p{název}, který představuje kategorii Unicode nebo pojmenovaný blok, nemůže do části \p{ tohoto elementu zahrnout vložené mezery. Pokud zahrnete prázdnou mezeru, prvek vyvolá ArgumentException při běhu programu.

Povolení této možnosti pomáhá zjednodušit regulární výrazy, které jsou často obtížné analyzovat a pochopit. Zlepšuje čitelnost a umožňuje dokumentovat regulární výraz.

Následující příklad definuje následující vzor regulárního výrazu:

\b \(? ( (?>\w+) ,?\s? )+ [\.!?] \)? # Matches an entire sentence.

Tento vzor je podobný vzoru definovanému v části Pouze explicitní zachycení, s tím rozdílem, že používá možnost RegexOptions.IgnorePatternWhitespace k ignorování mezer ve vzoru.

using System;
using System.Text.RegularExpressions;

public class Whitespace1Example
{
    public static void Main()
    {
        string input = "This is the first sentence. Is it the beginning " +
                       "of a literary masterpiece? I think not. Instead, " +
                       "it is a nonsensical paragraph.";
        string pattern = @"\b \(? ( (?>\w+) ,?\s? )+ [\.!?] \)? # Matches an entire sentence.";

        foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnorePatternWhitespace))
            Console.WriteLine(match.Value);
    }
}
// The example displays the following output:
//       This is the first sentence.
//       Is it the beginning of a literary masterpiece?
//       I think not.
//       Instead, it is a nonsensical paragraph.
Imports System.Text.RegularExpressions

Module Whitespace1Example
    Public Sub Main()
        Dim input As String = "This is the first sentence. Is it the beginning " +
                              "of a literary masterpiece? I think not. Instead, " +
                              "it is a nonsensical paragraph."
        Dim pattern As String = "\b \(? ( (?>\w+) ,?\s? )+  [\.!?] \)? # Matches an entire sentence."

        For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnorePatternWhitespace)
            Console.WriteLine(match.Value)
        Next
    End Sub
End Module
' The example displays the following output:
'       This is the first sentence.
'       Is it the beginning of a literary masterpiece?
'       I think not.
'       Instead, it is a nonsensical paragraph.

Následující příklad používá volbu „vložený“ (?x) ke ignorování bílých míst ve vzoru.

using System;
using System.Text.RegularExpressions;

public class Whitespace2Example
{
    public static void Main()
    {
        string input = "This is the first sentence. Is it the beginning " +
                       "of a literary masterpiece? I think not. Instead, " +
                       "it is a nonsensical paragraph.";
        string pattern = @"(?x)\b \(? ( (?>\w+) ,?\s? )+  [\.!?] \)? # Matches an entire sentence.";

        foreach (Match match in Regex.Matches(input, pattern))
            Console.WriteLine(match.Value);
    }
}
// The example displays the following output:
//       This is the first sentence.
//       Is it the beginning of a literary masterpiece?
//       I think not.
//       Instead, it is a nonsensical paragraph.
Imports System.Text.RegularExpressions

Module Whitespace2Example
    Public Sub Main()
        Dim input As String = "This is the first sentence. Is it the beginning " +
                              "of a literary masterpiece? I think not. Instead, " +
                              "it is a nonsensical paragraph."
        Dim pattern As String = "(?x)\b \(? ( (?>\w+) ,?\s? )+  [\.!?] \)? # Matches an entire sentence."

        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine(match.Value)
        Next
    End Sub
End Module
' The example displays the following output:
'       This is the first sentence.
'       Is it the beginning of a literary masterpiece?
'       I think not.
'       Instead, it is a nonsensical paragraph.

Režim zprava doleva

Ve výchozím nastavení modul regulárních výrazů prohledává zleva doprava. Směr hledání můžete obrátit pomocí RegexOptions.RightToLeft možnosti. Hledání zprava doleva automaticky začíná na poslední pozici znaku řetězce. Pro metody porovnávání vzorů, které obsahují parametr počáteční pozice, například Regex.Match(String, Int32), zadaná počáteční pozice je index pozice znaku nejvíce vpravo, na které má hledání začínat.

Poznámka:

Režim vzoru zprava doleva je k dispozici pouze zadáním RegexOptions.RightToLeft hodnoty options parametru Regex konstruktoru třídy nebo statické metody porovnávání vzorů. Není k dispozici jako vložená možnost.

Příklad

Regulární výraz \bb\w+\s odpovídá slovům se dvěma nebo více znaky, které začínají písmenem "b" a za nimi následuje prázdný znak. V následujícím příkladu se vstupní řetězec skládá ze tří slov, která obsahují jeden nebo více znaků "b". První a druhá slova začínají slovem "b" a třetí slovo končí slovem "b". Jak ukazuje výstup z příkladu hledání zprava doleva, pouze první a druhá slova odpovídají vzoru regulárního výrazu s druhým slovem, které se shoduje jako první.

using System;
using System.Text.RegularExpressions;

public class RTL1Example
{
    public static void Main()
    {
        string pattern = @"\bb\w+\s";
        string input = "build band tab";
        foreach (Match match in Regex.Matches(input, pattern, RegexOptions.RightToLeft))
            Console.WriteLine($"'{match.Value}' found at position {match.Index}.");
    }
}
// The example displays the following output:
//       'band ' found at position 6.
//       'build ' found at position 0.
Imports System.Text.RegularExpressions

Module RTL1Example
    Public Sub Main()
        Dim pattern As String = "\bb\w+\s"
        Dim input As String = "build band tab"
        For Each match As Match In Regex.Matches(input, pattern, RegexOptions.RightToLeft)
            Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
        Next
    End Sub
End Module
' The example displays the following output:
'       'band ' found at position 6.
'       'build ' found at position 0.

Pořadí vyhodnocení

Možnost RegexOptions.RightToLeft změní směr hledání a také obrátí pořadí, ve kterém se vyhodnocuje vzor regulárního výrazu. Při hledání zprava doleva se vzor hledání čte zprava doleva. Toto rozlišení je důležité, protože to může mít vliv na věci, jako jsou zachytávací skupiny a zpětné reference. Výraz například Regex.Match("abcabc", @"\1(abc)", RegexOptions.RightToLeft) najde shodu abcabc, ale v hledání zleva doprava (Regex.Match("abcabc", @"\1(abc)", RegexOptions.None)) se nenajde žádná shoda. Je to proto, že element (abc) musí být vyhodnocen před číslovaným zachycovacím elementem skupiny (\1), aby byla nalezena shoda.

Kontrolní výrazy lookahead a lookbehind

Umístění shody pro lookahead ((?=subexpression)) nebo lookbehind ((?<=subexpression)) při vyhledávání zprava doleva se nezmění. Kontrolní výrazy lookahead vypadají napravo od aktuálního umístění shody; kontrolní výrazy lookbehind vypadají vlevo od aktuálního umístění shody.

Tip

Bez ohledu na to, jestli je vyhledávání prováděno zprava doleva nebo jinak, jsou funkce zpětného hledání implementovány pomocí vyhledávání zprava doleva, které začíná na aktuálním místě shody.

Regulární výraz (?<=\d{1,2}\s)\w+,\s\d{4} například používá aserci lookbehind k otestování data, které předchází názvu měsíce. Regulární výraz se pak shoduje s měsícem a rokem. Informace o asertních výrazech lookahead a lookbehind naleznete v tématu Seskupování konstruktorů.

using System;
using System.Text.RegularExpressions;

public class RTL2Example
{
    public static void Main()
    {
        string[] inputs = { "1 May, 1917", "June 16, 2003" };
        string pattern = @"(?<=\d{1,2}\s)\w+,\s\d{4}";

        foreach (string input in inputs)
        {
            Match match = Regex.Match(input, pattern, RegexOptions.RightToLeft);
            if (match.Success)
                Console.WriteLine($"The date occurs in {match.Value}.");
            else
                Console.WriteLine($"{input} does not match.");
        }
    }
}

// The example displays the following output:
//       The date occurs in May, 1917.
//       June 16, 2003 does not match.
Imports System.Text.RegularExpressions

Module RTL2Example
    Public Sub Main()
        Dim inputs() As String = {"1 May, 1917", "June 16, 2003"}
        Dim pattern As String = "(?<=\d{1,2}\s)\w+,\s\d{4}"

        For Each input As String In inputs
            Dim match As Match = Regex.Match(input, pattern, RegexOptions.RightToLeft)
            If match.Success Then
                Console.WriteLine("The date occurs in {0}.", match.Value)
            Else
                Console.WriteLine("{0} does not match.", input)
            End If
        Next
    End Sub
End Module

' The example displays the following output:
'       The date occurs in May, 1917.
'       June 16, 2003 does not match.

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

Vzor Popis
(?<=\d{1,2}\s) Začátek shody musí předcházet jedna nebo dvě desetinná číslice následovaná mezerou.
\w+ Porovná jeden nebo více znaků slova.
, Porovná jeden znak čárky.
\s Porovná prázdný znak.
\d{4} Porovná čtyři desítkové číslice.

Chování shod ECMAScriptu

Modul regulárních výrazů ve výchozím nastavení používá kanonické chování při porovnávání vzoru regulárního výrazu se vstupním textem. Modul regulárních výrazů však můžete instruovat, aby používal odpovídající chování ECMAScriptu zadáním RegexOptions.ECMAScript možnosti.

Poznámka:

Chování kompatibilní s ECMAScriptem je k dispozici pouze zadáním RegexOptions.ECMAScript hodnoty options parametru Regex konstruktoru třídy nebo statické metody porovnávání vzorů. Není k dispozici jako vložená možnost.

Možnost RegexOptions.ECMAScript lze kombinovat pouze s možností RegexOptions.IgnoreCase a RegexOptions.Multiline. Použití jakékoli jiné možnosti v regulárním výrazu má za následek znak .ArgumentOutOfRangeException

Chování ECMAScriptu a kanonických regulárních výrazů se liší ve třech oblastech: syntaxe třídy znaků, samokazování na zachytávání skupin a osmičková a zpětná interpretace.

  • Syntaxe třídy znaků Vzhledem k tomu, že kanonické regulární výrazy podporují Unicode, zatímco ECMAScript ne, třídy znaků v ECMAScript mají omezenější syntaxi a některé prvky jazyka třídy znaků mají jiný význam. ECMAScript například nepodporuje jazykové elementy, jako je kategorie Unicode nebo blokové prvky \p a \P. Podobně je prvek, \w který odpovídá znaku slova, ekvivalentní [a-zA-Z_0-9] třídě znaků při použití ECMAScriptu a [\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}\p{Lm}] při použití kanonického chování. Další informace naleznete v tématu Třídy znaků.

    Následující příklad ukazuje rozdíl mezi kanonickým vzorem a porovnáváním vzorů ECMAScript. Definuje regulární výraz, \b(\w+\s*)+který odpovídá slovům následovaným prázdnými znaky. Vstup se skládá ze dvou řetězců, jednoho, který používá znakovou sadu latinky a druhou, která používá znakovou sadu cyrilice. Jak ukazuje výstup, volání Regex.IsMatch(String, String, RegexOptions) metody, která používá porovnávání ECMAScript, neodpovídá slovům cyrilice, zatímco volání metody, která používá kanonické porovnávání, odpovídá těmto slovům.

    using System;
    using System.Text.RegularExpressions;
    
    public class EcmaScriptExample
    {
        public static void Main()
        {
            string[] values = { "целый мир", "the whole world" };
            string pattern = @"\b(\w+\s*)+";
            foreach (var value in values)
            {
                Console.Write("Canonical matching: ");
                if (Regex.IsMatch(value, pattern))
                    Console.WriteLine($"'{value}' matches the pattern.");
                else
                    Console.WriteLine($"{value} does not match the pattern.");
    
                Console.Write("ECMAScript matching: ");
                if (Regex.IsMatch(value, pattern, RegexOptions.ECMAScript))
                    Console.WriteLine($"'{value}' matches the pattern.");
                else
                    Console.WriteLine($"{value} does not match the pattern.");
                Console.WriteLine();
            }
        }
    }
    // The example displays the following output:
    //       Canonical matching: 'целый мир' matches the pattern.
    //       ECMAScript matching: целый мир does not match the pattern.
    //
    //       Canonical matching: 'the whole world' matches the pattern.
    //       ECMAScript matching: 'the whole world' matches the pattern.
    
    Imports System.Text.RegularExpressions
    
    Module Ecma1Example
        Public Sub Main()
            Dim values() As String = {"целый мир", "the whole world"}
            Dim pattern As String = "\b(\w+\s*)+"
            For Each value In values
                Console.Write("Canonical matching: ")
                If Regex.IsMatch(value, pattern) Then
                    Console.WriteLine("'{0}' matches the pattern.", value)
                Else
                    Console.WriteLine("{0} does not match the pattern.", value)
                End If
    
                Console.Write("ECMAScript matching: ")
                If Regex.IsMatch(value, pattern, RegexOptions.ECMAScript) Then
                    Console.WriteLine("'{0}' matches the pattern.", value)
                Else
                    Console.WriteLine("{0} does not match the pattern.", value)
                End If
                Console.WriteLine()
            Next
        End Sub
    End Module
    ' The example displays the following output:
    '       Canonical matching: 'целый мир' matches the pattern.
    '       ECMAScript matching: целый мир does not match the pattern.
    '       
    '       Canonical matching: 'the whole world' matches the pattern.
    '       ECMAScript matching: 'the whole world' matches the pattern.
    
  • Samoodkazující se zachytávací skupiny Třída zachycení regulárního výrazu se zpětnou referencí na sebe musí být aktualizována při každé iteraci zachycení. Jak ukazuje následující příklad, tato funkce umožňuje regulárnímu výrazu ((a+)(\1) ?)+ odpovídat vstupnímu řetězci "aa aaaaaaa" při použití ECMAScriptu, ale ne při použití kanonické shody.

    using System;
    using System.Text.RegularExpressions;
    
    public class EcmaScript2Example
    {
        static string pattern;
    
        public static void Main()
        {
            string input = "aa aaaa aaaaaa ";
            pattern = @"((a+)(\1) ?)+";
    
            // Match input using canonical matching.
            AnalyzeMatch(Regex.Match(input, pattern));
    
            // Match input using ECMAScript.
            AnalyzeMatch(Regex.Match(input, pattern, RegexOptions.ECMAScript));
        }
    
        private static void AnalyzeMatch(Match m)
        {
            if (m.Success)
            {
                Console.WriteLine($"'{pattern}' matches {m.Value} at position {m.Index}.");
                int grpCtr = 0;
                foreach (Group grp in m.Groups)
                {
                    Console.WriteLine($"   {grpCtr}: '{grp.Value}'");
                    grpCtr++;
                    int capCtr = 0;
                    foreach (Capture cap in grp.Captures)
                    {
                        Console.WriteLine($"      {capCtr}: '{cap.Value}'");
                        capCtr++;
                    }
                }
            }
            else
            {
                Console.WriteLine("No match found.");
            }
            Console.WriteLine();
        }
    }
    // The example displays the following output:
    //    No match found.
    //
    //    '((a+)(\1) ?)+' matches aa aaaa aaaaaa  at position 0.
    //       0: 'aa aaaa aaaaaa '
    //          0: 'aa aaaa aaaaaa '
    //       1: 'aaaaaa '
    //          0: 'aa '
    //          1: 'aaaa '
    //          2: 'aaaaaa '
    //       2: 'aa'
    //          0: 'aa'
    //          1: 'aa'
    //          2: 'aa'
    //       3: 'aaaa '
    //          0: ''
    //          1: 'aa '
    //          2: 'aaaa '
    
    Imports System.Text.RegularExpressions
    
    Module Ecma2Example
        Dim pattern As String
    
        Public Sub Main()
            Dim input As String = "aa aaaa aaaaaa "
            pattern = "((a+)(\1) ?)+"
    
            ' Match input using canonical matching.
            AnalyzeMatch(Regex.Match(input, pattern))
    
            ' Match input using ECMAScript.
            AnalyzeMatch(Regex.Match(input, pattern, RegexOptions.ECMAScript))
        End Sub
    
        Private Sub AnalyzeMatch(m As Match)
            If m.Success Then
                Console.WriteLine("'{0}' matches {1} at position {2}.",
                                  pattern, m.Value, m.Index)
                Dim grpCtr As Integer = 0
                For Each grp As Group In m.Groups
                    Console.WriteLine("   {0}: '{1}'", grpCtr, grp.Value)
                    grpCtr += 1
                    Dim capCtr As Integer = 0
                    For Each cap As Capture In grp.Captures
                        Console.WriteLine("      {0}: '{1}'", capCtr, cap.Value)
                        capCtr += 1
                    Next
                Next
            Else
                Console.WriteLine("No match found.")
            End If
            Console.WriteLine()
        End Sub
    End Module
    ' The example displays the following output:
    '    No match found.
    '    
    '    '((a+)(\1) ?)+' matches aa aaaa aaaaaa  at position 0.
    '       0: 'aa aaaa aaaaaa '
    '          0: 'aa aaaa aaaaaa '
    '       1: 'aaaaaa '
    '          0: 'aa '
    '          1: 'aaaa '
    '          2: 'aaaaaa '
    '       2: 'aa'
    '          0: 'aa'
    '          1: 'aa'
    '          2: 'aa'
    '       3: 'aaaa '
    '          0: ''
    '          1: 'aa '
    '          2: 'aaaa '
    

    Regulární výraz je definován, jak je znázorněno v následující tabulce.

    Vzor Popis
    (a+) Porovná písmeno "a" jednou nebo vícekrát. Toto je druhá skupina pro zachytávání.
    (\1) Porovnejte podřetězec zachycený první zachytávací skupinou. Toto je třetí zachytávající skupina.
    ? Porovná žádný nebo jeden znak mezery.
    ((a+)(\1) ?)+ Porovná vzor jednoho nebo více znaků "a" následovaný řetězcem, který odpovídá první zachycené skupině následované nulou nebo jednou mezerou jednou nebo vícekrát. Toto je první zachytávající skupina.
  • Řešení nejednoznačností mezi osmičkovými únikovými sekvencemi a zpětnými odkazy. Následující tabulka shrnuje rozdíly v osmičkovém a zpětném odvozování pomocí kanonických a ECMAScript regulárních výrazů.

    Regulární výraz Kanonické chování Chování ECMAScriptu
    \0 následované 0 až 2 osmičkovými číslicemi Interpretovat jako osmičkovou soustavu. \044 Například se vždy interpretuje jako osmičková hodnota a znamená "$". Stejné chování.
    \ následovaná číslicí od 1 do 9, za kterou nenásledují žádné další desetinné číslice, Interpretuje se jako zpětná reference. Například \9 vždy znamená zpětnou referenci 9, i když by devátá zachycená skupina neexistovala. Pokud skupina zachycení neexistuje, analyzátor regulárních výrazů vyvolá výjimku ArgumentException. Pokud existuje zachytávací skupina pro jednu desetinnou číslici, odkazuje zpět na tuto číslici. V opačném případě interpretujte hodnotu jako literál.
    \ následovaná číslicí od 1 do 9, za kterou následuje další desetinná čísla. Číslice interpretujte jako desetinnou hodnotu. Pokud tato zachycovací skupina existuje, interpretujte výraz jako zpětný odkaz.

    Jinak interpretujte vedoucí osmičkové číslice až do osmičkového čísla 377; to znamená, že zvažte pouze dolních 8 bitů hodnoty. Interpretuje zbývající číslice jako literály. Pokud například ve výrazu \3000existuje zachytávání skupiny 300, interpretujte ji jako backreference 300. Pokud zachytávání skupiny 300 neexistuje, interpretujte ji jako osmičkové číslo 300 následované 0.
    Interpretovat jako zpětnou referenci převodem co největšího počtu číslic na desetinnou hodnotu, která může odkazovat na zachycení. Pokud nelze převést žádné číslice, považujte celé číslo za osmičkové s použitím počátečních osmičkových číslic až do osmičkového čísla 377; zbylé číslice považujte za literály.

Porovnat s využitím invariantní kultury

Když modul regulárních výrazů ve výchozím nastavení provádí porovnávání bez rozlišování malých a velkých písmen, používá konvence velikosti písmen aktuální jazykové verze k určení ekvivalentních velkých a malých písmen.

Toto chování je však nežádoucí u některých typů porovnání, zejména při porovnávání uživatelských vstupů s názvy systémových prostředků, jako jsou hesla, soubory nebo adresy URL. Následující příklad znázorňuje takový scénář. Kód je určený k blokování přístupu k libovolnému prostředku, jehož adresa URL je před FILE://. Regulární výraz se pokusí srovnávat s řetězcem nerorezlšující malá a velká písmena pomocí regulárního výrazu $FILE://. Pokud je však aktuální systémová kultura tr-TR (turečtina-Türkiye), "I" není verzí velkého písmena pro "i". V důsledku toho volání Regex.IsMatch metody vrátí falsea přístup k souboru je povolen.

CultureInfo defaultCulture = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = new CultureInfo("tr-TR");

string input = "file://c:/Documents.MyReport.doc";
string pattern = "FILE://";

Console.WriteLine($"Culture-sensitive matching ({Thread.CurrentThread.CurrentCulture.Name} culture)...");
if (Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase))
    Console.WriteLine("URLs that access files are not allowed.");
else
    Console.WriteLine($"Access to {input} is allowed.");

Thread.CurrentThread.CurrentCulture = defaultCulture;
// The example displays the following output:
//       Culture-sensitive matching (tr-TR culture)...
//       Access to file://c:/Documents.MyReport.doc is allowed.
Dim defaultCulture As CultureInfo = Thread.CurrentThread.CurrentCulture
Thread.CurrentThread.CurrentCulture = New CultureInfo("tr-TR")

Dim input As String = "file://c:/Documents.MyReport.doc"
Dim pattern As String = "$FILE://"

Console.WriteLine("Culture-sensitive matching ({0} culture)...",
                  Thread.CurrentThread.CurrentCulture.Name)
If Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase) Then
    Console.WriteLine("URLs that access files are not allowed.")
Else
    Console.WriteLine("Access to {0} is allowed.", input)
End If

Thread.CurrentThread.CurrentCulture = defaultCulture
' The example displays the following output:
'       Culture-sensitive matching (tr-TR culture)...
'       Access to file://c:/Documents.MyReport.doc is allowed.

Poznámka:

Další informace o porovnání řetězců, která rozlišují velká a malá písmena a používají invariantní jazykovou verzi, naleznete v tématu Osvědčené postupy pro používání řetězců.

Místo použití porovnání aktuální jazykové verze bez rozlišování malých a velkých písmen můžete určit RegexOptions.CultureInvariant možnost ignorovat kulturní rozdíly v jazyce a používat konvence invariantní jazykové verze.

Poznámka:

Porovnání pomocí invariantní jazykové verze je k dispozici pouze zásobováním hodnoty RegexOptions.CultureInvariant do parametru options konstruktoru třídy nebo do statické metody pro rozpoznávání vzorů Regex. Není k dispozici jako integrovaná možnost.

Následující příklad je identický s předchozím příkladem, s tím rozdílem, že statická Regex.IsMatch(String, String, RegexOptions) metoda je volána s možnostmi, které zahrnují RegexOptions.CultureInvariant. I když je aktuální jazyková verze nastavená na turečtinu (Türkiye), modul regulárních výrazů je schopen úspěšně rozpoznat "FILE" a "file" a blokovat přístup k souborovému prostředku.

CultureInfo defaultCulture = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = new CultureInfo("tr-TR");

string input = "file://c:/Documents.MyReport.doc";
string pattern = "FILE://";

Console.WriteLine("Culture-insensitive matching...");
if (Regex.IsMatch(input, pattern,
                  RegexOptions.IgnoreCase | RegexOptions.CultureInvariant))
    Console.WriteLine("URLs that access files are not allowed.");
else
    Console.WriteLine($"Access to {input} is allowed.");

Thread.CurrentThread.CurrentCulture = defaultCulture;
// The example displays the following output:
//       Culture-insensitive matching...
//       URLs that access files are not allowed.
Dim defaultCulture As CultureInfo = Thread.CurrentThread.CurrentCulture
Thread.CurrentThread.CurrentCulture = New CultureInfo("tr-TR")

Dim input As String = "file://c:/Documents.MyReport.doc"
Dim pattern As String = "$FILE://"

Console.WriteLine("Culture-insensitive matching...")
If Regex.IsMatch(input, pattern,
               RegexOptions.IgnoreCase Or RegexOptions.CultureInvariant) Then
    Console.WriteLine("URLs that access files are not allowed.")
Else
    Console.WriteLine("Access to {0} is allowed.", input)
End If
Thread.CurrentThread.CurrentCulture = defaultCulture
' The example displays the following output:
'        Culture-insensitive matching...
'        URLs that access files are not allowed.

Režim bez návratu

Ve výchozím nastavení používá modul regulárních výrazů .NET zpětné procházení k pokusu o vyhledání shody vzorů. Modul zpětného navracení je takový, který se snaží shodovat s jedním vzorem, a pokud se to nezdaří, vrátí se zpět a pokusí se spárovat alternativní vzor atd. Backtrackingový modul je pro typické případy velmi rychlý, ale zpomaluje se s nárůstem počtu alternativ vzorů, což může vést ke katastrofickému backtrackingu. Možnost RegexOptions.NonBacktracking , která byla zavedena v .NET 7, nepoužívá navracení a zabraňuje tomu nejhoršímu scénáři. Jejím cílem je poskytovat konzistentně dobré chování bez ohledu na hledaný vstup.

Možnost RegexOptions.NonBacktracking nepodporuje vše, co podporují ostatní integrované moduly. Konkrétně se tato možnost nedá použít ve spojení s RegexOptions.RightToLeft nebo RegexOptions.ECMAScript. Také neumožňuje následující konstrukce ve vzoru:

  • Atomické skupiny
  • Zpětné reference
  • Vyrovnávací skupiny
  • Podmíněné výrazy
  • Lookarounds
  • Spuštění kotev (\G)

RegexOptions.NonBacktracking má také jemný rozdíl, pokud jde o provádění. Pokud je skupina zachycení ve smyčce, většina modulů regex (non-.NET) poskytuje pouze poslední odpovídající hodnotu pro daný záznam. Nicméně, engine regulárních výrazů .NET sleduje všechny hodnoty zachycené ve smyčce a poskytuje k nim přístup. Možnost RegexOptions.NonBacktracking je podobná většině ostatních implementací regulárních výrazů a podporuje pouze poskytnutí konečného zachycení.

Další informace o navracení najdete v tématu Navracení v regulárních výrazech.

Viz také