Sdílet prostřednictvím


Konstrukce alternace v regulárních výrazech

Konstrukce alternace upravují regulární výraz tak, aby povolily buď/nebo, nebo podmíněné porovnávání. .NET podporuje tři konstrukce alternace:

Porovnávání vzorů s |

Svislý znak pruhu (|) můžete použít ke spárování libovolné řady vzorů, kde | jednotlivé vzory odděluje.

Stejně jako u kladné třídy znaků lze znak | použít ke shodě s kterýmkoli z několika jednotlivých znaků. V následujícím příkladu se k vyhledání výskytů slov "gray" nebo "grey" v řetězci používá kladná třída znaků a buď/nebo párování vzorů s |. V tomto případě | znak vytvoří regulární výraz, který je obsáhlejší.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      // Regular expression using character class.
      string pattern1 = @"\bgr[ae]y\b";
      // Regular expression using either/or.
      string pattern2 = @"\bgr(a|e)y\b";

      string input = "The gray wolf blended in among the grey rocks.";
      foreach (Match match in Regex.Matches(input, pattern1))
         Console.WriteLine($"'{match.Value}' found at position {match.Index}");
      Console.WriteLine();
      foreach (Match match in Regex.Matches(input, pattern2))
         Console.WriteLine($"'{match.Value}' found at position {match.Index}");
   }
}
// The example displays the following output:
//       'gray' found at position 4
//       'grey' found at position 35
//
//       'gray' found at position 4
//       'grey' found at position 35
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        ' Regular expression using character class.
        Dim pattern1 As String = "\bgr[ae]y\b"
        ' Regular expression using either/or.
        Dim pattern2 As String = "\bgr(a|e)y\b"

        Dim input As String = "The gray wolf blended in among the grey rocks."
        For Each match As Match In Regex.Matches(input, pattern1)
            Console.WriteLine("'{0}' found at position {1}", _
                              match.Value, match.Index)
        Next
        Console.WriteLine()
        For Each match As Match In Regex.Matches(input, pattern2)
            Console.WriteLine("'{0}' found at position {1}", _
                              match.Value, match.Index)
        Next
    End Sub
End Module
' The example displays the following output:
'       'gray' found at position 4
'       'grey' found at position 35
'       
'       'gray' found at position 4
'       'grey' found at position 35           

Regulární výraz, který používá znak |, \bgr(a|e)y\b, je interpretován, jak je znázorněno v následující tabulce:

Vzor Popis
\b Začněte na hranici slova.
gr Najdi znaky "gr".
(a|e) Porovná buď se znakem „a“, nebo s „e“.
y\b Najdi shodu "y" na hranici slova.

Znak | lze také použít k provedení alternativní shody s více znaky nebo podvýrazy, které mohou zahrnovat libovolnou kombinaci znakových literálů a elementů jazyka regulárních výrazů. (Třída znaků neposkytuje tuto funkci.) Následující příklad používá | znak k extrahování čísla sociálního pojištění USA (SSN), což je 9místné číslo s formátem ddd ddd dddd--, nebo identifikační číslo zaměstnavatele (EIN), což je 9místné číslo s formátem dd.-

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b";
      string input = "01-9999999 020-333333 777-88-9999";
      Console.WriteLine($"Matches for {pattern}:");
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine($"   {match.Value} at position {match.Index}");
   }
}
// The example displays the following output:
//       Matches for \b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b:
//          01-9999999 at position 0
//          777-88-9999 at position 22
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "\b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b"
        Dim input As String = "01-9999999 020-333333 777-88-9999"
        Console.WriteLine("Matches for {0}:", pattern)
        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine("   {0} at position {1}", match.Value, match.Index)
        Next
    End Sub
End Module
' The example displays the following output:
'       Matches for \b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b:
'          01-9999999 at position 0
'          777-88-9999 at position 22

Regulární výraz \b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b se interpretuje, jak je znázorněno v následující tabulce:

Vzor Popis
\b Začněte na hranici slova.
(\d{2}-\d{7}|\d{3}-\d{2}-\d{4}) Porovná jednu z následujících hodnot: dvě desetinné číslice následované pomlčkou následovanou sedmi desetinnými číslicemi; nebo tři desetinná číslice, spojovník, dvě desetinné číslice, další spojovník a čtyři desetinné číslice.
\b Ukončete shodu na hranici slova.

Podmíněné porovnávání s výrazem

Tento prvek jazyka se pokouší shodovat s jedním ze dvou vzorů v závislosti na tom, jestli se může shodovat s počátečním vzorem. Jeho syntaxe je:

(?( výraz)Ano)

nebo

(?( výraz)ano|ne)

cs-CZ: kde expression je počáteční vzor k porovnání, yes je vzor k porovnání, pokud expression je nalezena, a no je volitelný vzor k porovnání, pokud expression není nalezena (pokud není zadán vzor no, je to ekvivalent prázdného no). Modul regulárních výrazů považuje výraz za výraz s nulovou šířkou. To znamená, že nepostupuje ve vstupním streamu po vyhodnocení výrazu. Proto je tento konstruktor ekvivalentní následujícímu:

(?(?= výraz)ano|ne)

where (?=výraz) je asertivní konstrukce s nulovou šířkou. (Další informace najdete v tématu Seskupovací konstrukty.) Vzhledem k tomu, že modul regulárních výrazů interpretuje výraz jako ukotvení (nulovou šířku výrazu), výraz musí být buď nulová šířka výrazu (další informace najdete v Ukotvení) nebo dílčí výraz, který je také obsažen v yes. V opačném případě nelze vzor ano spárovat.

Poznámka:

Pokud je výraz pojmenovanou nebo číslovanou zachytávací skupinou, konstruktor alternace se interpretuje jako test zachycení; další informace najdete v další části Podmíněné porovnávání na základě platné zachytávací skupiny. Jinými slovy, engine regulárních výrazů se nepokouší shodovat zachycený podřetězec, ale místo toho testuje přítomnost nebo nepřítomnost skupiny.

Následující příklad je varianta příkladu, který se zobrazí v oddílu Buď/nebo Porovnávání vzorů s | . Používá podmíněné porovnávání k určení, zda první tři znaky za hranicí slova jsou dvě číslice následované pomlčkou. Pokud ano, pokusí se shodovat s identifikačním číslem zaměstnavatele (EIN). Pokud ne, pokusí se najít odpovídající číslo sociálního pojištění USA (SSN).

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b(?(\d{2}-)\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b";
      string input = "01-9999999 020-333333 777-88-9999";
      Console.WriteLine($"Matches for {pattern}:");
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine($"   {match.Value} at position {match.Index}");
   }
}
// The example displays the following output:
//       Matches for \b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b:
//          01-9999999 at position 0
//          777-88-9999 at position 22
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "\b(?(\d{2}-)\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b"
        Dim input As String = "01-9999999 020-333333 777-88-9999"
        Console.WriteLine("Matches for {0}:", pattern)
        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine("   {0} at position {1}", match.Value, match.Index)
        Next
    End Sub
End Module
' The example displays the following output:
'       Matches for \b(?(\d{2}-)\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b:
'          01-9999999 at position 0
'          777-88-9999 at position 22

Vzor regulárního výrazu \b(?(\d{2}-)\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b je interpretován, jak je znázorněno v následující tabulce:

Vzor Popis
\b Začněte na hranici slova.
(?(\d{2}-) Určete, jestli se další tři znaky skládají ze dvou číslic následovaných pomlčkou.
\d{2}-\d{7} Pokud předchozí vzor odpovídá, spárujte dvě číslice následované spojovníkem následovaným sedmi číslicemi.
\d{3}-\d{2}-\d{4} Pokud se předchozí vzor neshoduje, porovná tři desetinná čísla, spojovník, dvě desetinné číslice, další spojovník a čtyři desetinné číslice.
\b Najdi hranici slova.

Podmíněné porovnávání na základě platné zachycené skupiny

Tento prvek jazyka se pokusí porovnat s jedním z dvou vzorů, v závislosti na tom, zda odpovídá určené zachycovací skupině. Jeho syntaxe je:

(?( Jméno)Ano)

nebo

(?( Jméno)Ano|Ne)

nebo

(?( číslo)Ano)

nebo

(?( číslo)Ano|Ne)

kde name je název a number je číslo zachycovací skupiny, yes je výraz, který se má shodovat, pokud name nebo number má shodu, a no je volitelný výraz, který se má shodovat, pokud ne (pokud není zadán vzor no, je to ekvivalentní prázdnému no).

Pokud název neodpovídá názvu zachytávací skupiny, která se používá ve vzoru regulárního výrazu, je konstrukce alternace interpretována jako test výrazu, jak je vysvětleno v předchozí části. Obvykle to znamená, že výraz se vyhodnotí jako false. Pokud číslo neodpovídá číslované zachycené skupině, která se používá ve vzoru regulárního výrazu, vyvolá modul regulárních výrazů hodnotu ArgumentException.

Následující příklad je varianta příkladu, který se zobrazí v oddílu Buď/nebo Porovnávání vzorů s | . Používá zachytávací skupinu pojmenovanou n2, která se skládá ze dvou číslic následovaných pomlčkou. Konstruktor alternace testuje, zda byla tato zachytávání skupina spárována ve vstupním řetězci. Pokud ano, alternativní konstrukce se pokusí shodovat s posledními sedmi číslicemi devítimístného amerického identifikačního čísla zaměstnavatele (EIN). Pokud tomu tak není, pokouší se najít shodu s devíticiferným číslem amerického sociálního zabezpečení (SSN).

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b(?<n2>\d{2}-)?(?(n2)\d{7}|\d{3}-\d{2}-\d{4})\b";
      string input = "01-9999999 020-333333 777-88-9999";
      Console.WriteLine($"Matches for {pattern}:");
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine($"   {match.Value} at position {match.Index}");
   }
}
// The example displays the following output:
//       Matches for \b(?<n2>\d{2}-)?(?(n2)\d{7}|\d{3}-\d{2}-\d{4})\b:
//          01-9999999 at position 0
//          777-88-9999 at position 22
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "\b(?<n2>\d{2}-)?(?(n2)\d{7}|\d{3}-\d{2}-\d{4})\b"
        Dim input As String = "01-9999999 020-333333 777-88-9999"
        Console.WriteLine("Matches for {0}:", pattern)
        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine("   {0} at position {1}", match.Value, match.Index)
        Next
    End Sub
End Module

Vzor regulárního výrazu \b(?<n2>\d{2}-)?(?(n2)\d{7}|\d{3}-\d{2}-\d{4})\b se interpretuje tak, jak je znázorněno v tabulce níže.

Vzor Popis
\b Začněte na hranici slova.
(?<n2>\d{2}-)? Odpovídá žádnému nebo jednomu výskytu dvou číslic následovaných pomlčkou. Pojmenujte tuto zachytávací skupinu n2.
(?(n2) Otestujte, zda se n2 shodoval ve vstupním řetězci.
\d{7} Pokud n2 byl nalezen, shodují sedm desetinných číslic.
|\d{3}-\d{2}-\d{4} Pokud se n2 neshoduje, spárujte tři desetinná místa, spojovník, dvě desetinná místa, další spojovník a čtyři desetinná místa.
\b Rozpozná hranici slova.

Variace tohoto příkladu, která místo pojmenované skupiny používá číslovaný skupinu, je znázorněna v následujícím příkladu. Vzor regulárního výrazu je \b(\d{2}-)?(?(1)\d{7}|\d{3}-\d{2}-\d{4})\b.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b(\d{2}-)?(?(1)\d{7}|\d{3}-\d{2}-\d{4})\b";
      string input = "01-9999999 020-333333 777-88-9999";
      Console.WriteLine($"Matches for {pattern}:");
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine($"   {match.Value} at position {match.Index}");
   }
}
// The example display the following output:
//       Matches for \b(\d{2}-)?(?(1)\d{7}|\d{3}-\d{2}-\d{4})\b:
//          01-9999999 at position 0
//          777-88-9999 at position 22
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "\b(\d{2}-)?(?(1)\d{7}|\d{3}-\d{2}-\d{4})\b"
        Dim input As String = "01-9999999 020-333333 777-88-9999"
        Console.WriteLine("Matches for {0}:", pattern)
        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine("   {0} at position {1}", match.Value, match.Index)
        Next
    End Sub
End Module
' The example displays the following output:
'       Matches for \b(\d{2}-)?(?(1)\d{7}|\d{3}-\d{2}-\d{4})\b:
'          01-9999999 at position 0
'          777-88-9999 at position 22

Viz také