Konstrukcje alternacyjne w wyrażeniach regularnych

Konstrukcje naprzemienne modyfikują wyrażenie regularne, aby włączyć/lub dopasowanie warunkowe. Platforma .NET obsługuje trzy konstrukcje zmiany:

Dopasowywanie wzorca za pomocą |

Możesz użyć znaku paska pionowego (|), aby dopasować dowolny z serii wzorców, gdzie | znak oddziela każdy wzorzec.

Podobnie jak w klasie znaków dodatnich, | znak może być używany do dopasowania dowolnej z wielu pojedynczych znaków. W poniższym przykładzie użyto zarówno klasy znaku dodatniego, jak i/lub wzorca pasującego do | znaku w celu zlokalizowania wystąpień wyrazów "szary" lub "szary" w ciągu. W tym przypadku | znak tworzy wyrażenie regularne, które jest bardziej pełne.

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("'{0}' found at position {1}",
                           match.Value, match.Index);
      Console.WriteLine();
      foreach (Match match in Regex.Matches(input, pattern2))
         Console.WriteLine("'{0}' found at position {1}",
                           match.Value, 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           

Wyrażenie regularne używające | znaku \bgr(a|e)y\b, jest interpretowane, jak pokazano w poniższej tabeli:

Wzorzec opis
\b Rozpoczyna na granicy wyrazu.
gr Dopasuj znaki "gr".
(a|e) Dopasowuje znak „a” lub „e”.
y\b Dopasuj wartość "y" na granicy wyrazu.

Znak | może być również używany do wykonywania dopasowania z wieloma znakami lub podwyrażeniami, które mogą zawierać dowolną kombinację literałów znaków i elementów języka wyrażeń regularnych. (Klasa znaków nie udostępnia tej funkcji). W poniższym przykładzie | użyto znaku do wyodrębnienia numeru ubezpieczenia społecznego (SSN), który jest 9-cyfrową liczbą z formatem d-ddd dd- lub numerem identyfikacyjnym pracodawcy USA (EIN), który jest 9-cyfrową liczbą w formacie ddd.-

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 {0}:", pattern);
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine("   {0} at position {1}", match.Value, 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

Wyrażenie \b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b regularne jest interpretowane, jak pokazano w poniższej tabeli:

Wzorzec opis
\b Rozpoczyna na granicy wyrazu.
(\d{2}-\d{7}|\d{3}-\d{2}-\d{4}) Dopasuj jedną z następujących wartości: dwie cyfry dziesiętne, po których następuje łącznik, po którym następuje siedem cyfr dziesiętnych; lub trzy cyfry dziesiętne, łącznik, dwie cyfry dziesiętne, inny łącznik i cztery cyfry dziesiętne.
\b Kończy dopasowanie na granicy wyrazu.

Dopasowywanie warunkowe za pomocą wyrażenia

Ten element języka próbuje dopasować jeden z dwóch wzorców w zależności od tego, czy może być zgodny ze wzorcem początkowym. Jego składnia to:

(?(wyrażenie)tak)

lub

(?(wyrażenie)tak|nie)

gdzie wyrażenie jest początkowym wzorcem zgodnym, tak jest wzorzec do dopasowania, jeśli wyrażenie jest dopasowane, a nie jest opcjonalnym wzorcem dopasowania, jeśli wyrażenie nie jest zgodne (jeśli nie podano wzorca, jest to odpowiednik pustego nie). Aparat wyrażeń regularnych traktuje wyrażenie jako asercję o zerowej szerokości. Oznacza to, że aparat wyrażeń regularnych nie przechodzi do strumienia wejściowego po obliczeniu wyrażenia. W związku z tym ta konstrukcja jest równoważna następującym:

(?(?=wyrażenie)tak|nie)

gdzie (?=wyrażenie) jest konstrukcją asercji o zerowej szerokości. (Aby uzyskać więcej informacji, zobacz Konstrukcje grupowania. Ponieważ aparat wyrażeń regularnych interpretuje wyrażenie jako kotwicę (asercja o zerowej szerokości), wyrażenie musi być asercją o zerowej szerokości (aby uzyskać więcej informacji, zobacz Anchors) lub podwyrażenie, które jest również zawarte w tak. W przeciwnym razie nie można dopasować wzorca tak.

Uwaga

Jeśli wyrażenie jest nazwaną lub numerowaną grupą przechwytywania, konstrukcja zmiany jest interpretowana jako test przechwytywania. Aby uzyskać więcej informacji, zobacz następną sekcję Dopasowywanie warunkowe na podstawie prawidłowej grupy przechwytywania. Innymi słowy aparat wyrażeń regularnych nie próbuje dopasować przechwyconego podciągu, ale zamiast tego testuje obecność lub brak grupy.

Poniższy przykład to odmiana przykładu wyświetlana w sekcji Dopasowywanie wzorca lub z | . Używa dopasowania warunkowego, aby określić, czy pierwsze trzy znaki po granicy wyrazu to dwie cyfry, po których następuje łącznik. Jeśli tak, próbuje dopasować amerykański numer identyfikacyjny pracodawcy (EIN). Jeśli nie, próbuje dopasować numer ubezpieczenia społecznego (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 {0}:", pattern);
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine("   {0} at position {1}", match.Value, 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

Wzorzec \b(?(\d{2}-)\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b wyrażenia regularnego jest interpretowany, jak pokazano w poniższej tabeli:

Wzorzec opis
\b Rozpoczyna na granicy wyrazu.
(?(\d{2}-) Ustal, czy następne trzy znaki składają się z dwóch cyfr, po których następuje łącznik.
\d{2}-\d{7} Jeśli poprzedni wzorzec pasuje, dopasuj dwie cyfry, po których następuje łącznik, po którym następuje siedem cyfr.
\d{3}-\d{2}-\d{4} Jeśli poprzedni wzorzec nie jest zgodny, dopasuj trzy cyfry dziesiętne, łącznik, dwie cyfry dziesiętne, inny łącznik i cztery cyfry dziesiętne.
\b Dopasowuje granicę wyrazu.

Dopasowywanie warunkowe na podstawie prawidłowej przechwyconej grupy

Ten element języka próbuje dopasować jeden z dwóch wzorców w zależności od tego, czy pasował do określonej grupy przechwytywania. Jego składnia to:

(?(nazwa)tak)

lub

(?(nazwa)tak|nie)

lub

(?(number)yes)

lub

(?(number)yes no|)

gdzie nazwa to nazwa , a liczba jest liczbą grupy przechwytywania, tak jest wyrażeniem zgodnym, jeśli nazwa lub liczba ma dopasowanie, a nie jest opcjonalnym wyrażeniem, które ma być zgodne, jeśli nie (jeśli nie podano żadnego wzorca, jest to równoważne pustemu nie).

Jeśli nazwa nie odpowiada nazwie grupy przechwytywania używanej we wzorcu wyrażenia regularnego, konstrukcja zmiany jest interpretowana jako test wyrażeń, jak wyjaśniono w poprzedniej sekcji. Zazwyczaj oznacza to, że wyrażenie daje wartość false. Jeśli liczba nie odpowiada numerowanej grupie przechwytywania, która jest używana we wzorcu wyrażenia regularnego, aparat wyrażeń regularnych zgłasza wartość ArgumentException.

Poniższy przykład to odmiana przykładu wyświetlana w sekcji Dopasowywanie wzorca lub z | . Używa grupy przechwytywania o nazwie n2 , która składa się z dwóch cyfr, po których następuje łącznik. Konstrukcja zmiany sprawdza, czy ta grupa przechwytywania została dopasowana w ciągu wejściowym. Jeśli tak, konstrukcja przemienna próbuje dopasować ostatnie siedem cyfr dziewięciocyfrowego numeru identyfikacyjnego pracodawcy USA (EIN). Jeśli tak nie jest, próbuje dopasować dziewięć-cyfrowy numer ubezpieczenia społecznego (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 {0}:", pattern);
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine("   {0} at position {1}", match.Value, 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

Wzorzec \b(?<n2>\d{2}-)?(?(n2)\d{7}|\d{3}-\d{2}-\d{4})\b wyrażenia regularnego jest interpretowany, jak pokazano w poniższej tabeli:

Wzorzec opis
\b Rozpoczyna na granicy wyrazu.
(?<n2>\d{2}-)? Dopasuj zero lub jedno wystąpienie dwóch cyfr, po którym następuje łącznik. Nadaj tej grupie n2przechwytywania nazwę .
(?(n2) Sprawdź, czy n2 ciąg wejściowy został dopasowany.
\d{7} Jeśli n2 została dopasowana, dopasuj siedem cyfr dziesiętnych.
|\d{3}-\d{2}-\d{4} Jeśli n2 nie zostało dopasowane, dopasuj trzy cyfry dziesiętne, łącznik, dwie cyfry dziesiętne, inny łącznik i cztery cyfry dziesiętne.
\b Dopasowuje granicę wyrazu.

Odmiana tego przykładu, która używa grupy numerowanej zamiast nazwanej grupy, jest pokazana w poniższym przykładzie. Jego wzorzec wyrażenia regularnego to \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 {0}:", pattern);
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine("   {0} at position {1}", match.Value, 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

Zobacz też