Dela via


Alternationskonstruktioner i reguljära uttryck

Alternationskonstruktioner ändrar ett reguljärt uttryck för att aktivera antingen/eller villkorsstyrd matchning. .NET har stöd för tre alternationskonstruktioner:

Mönstermatchning med |

Du kan använda det lodräta stapeltecknet (|) för att matcha något av en serie mönster, där | tecknet separerar varje mönster.

Precis som den positiva teckenklassen | kan tecknet användas för att matcha ett av ett antal enskilda tecken. I följande exempel används både en positiv teckenklass och antingen/eller mönstermatchning med | tecknet för att hitta förekomster av orden "grå" eller "grå" i en sträng. I det här fallet | skapar tecknet ett reguljärt uttryck som är mer utförligt.

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           

Det reguljära uttryck som använder | tecknet , \bgr(a|e)y\btolkas enligt följande tabell:

Mönster beskrivning
\b Börja vid en ordgräns.
gr Matcha tecknen "gr".
(a|e) Matcha antingen ett "a" eller ett "e".
y\b Matcha ett "y" på en ordgräns.

Tecknet | kan också användas för att utföra en endera/eller matchning med flera tecken eller underuttryck, vilket kan inkludera valfri kombination av teckenliteraler och reguljära uttrycksspråkelement. (Teckenklassen tillhandahåller inte den här funktionen.) I följande exempel används | tecknet för att extrahera antingen ett U.S. Social Security Number (SSN), som är ett 9-siffrigt tal med formatet ddd dd-dddd- eller ett U.S. Employer Identification Number (EIN), som är ett 9-siffrigt nummer med formatet dd-ddddddd.

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

Det reguljära uttrycket \b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b tolkas enligt följande tabell:

Mönster beskrivning
\b Börja vid en ordgräns.
(\d{2}-\d{7}|\d{3}-\d{2}-\d{4}) Matcha något av följande: två decimaltal följt av ett bindestreck följt av sju decimaler. eller tre decimaltal, ett bindestreck, två decimalsiffror, ett annat bindestreck och fyra decimaler.
\b Avsluta matchningen vid en ordgräns.

Villkorsstyrd matchning med ett uttryck

Det här språkelementet försöker matcha ett av två mönster beroende på om det kan matcha ett inledande mönster. Syntaxen är:

(?(uttryck ) Ja )

eller

(?(uttryck ) Ja | Nej )

där uttrycket är det inledande mönstret som ska matchas, ja är det mönster som ska matchas om uttrycket matchas och nej är det valfria mönstret som matchar om uttrycket inte matchas (om inget mönster inte anges motsvarar det ett tomt nej). Motorn för reguljära uttryck behandlar uttrycket som en försäkran med noll bredd. Det innebär att motorn för reguljära uttryck inte avancerar i indataströmmen efter att uttrycket utvärderats. Den här konstruktionen motsvarar därför följande:

(?(?=uttryck ) Ja | Nej )

där (?=uttrycket) är en kontrollkonstruktion med noll bredd. (Mer information finns i Grupperingskonstruktioner.) Eftersom motorn för reguljära uttryck tolkar uttrycket som en fästpunkt (en försäkran med noll bredd) måste uttrycket antingen vara en försäkran med noll bredd (mer information finns i Fästpunkter) eller en underuttryck som också finns i ja. Annars kan ja-mönstret inte matchas.

Kommentar

Om uttrycket är en namngiven eller numrerad insamlingsgrupp tolkas växlingskonstruktionen som ett avbildningstest. Mer information finns i nästa avsnitt, Villkorsstyrd matchning baserat på en giltig avbildningsgrupp. Med andra ord försöker motorn för reguljära uttryck inte matcha den insamlade delsträngen, utan testar i stället för förekomsten eller frånvaron av gruppen.

Följande exempel är en variant av exemplet som visas i avsnittet Antingen/eller Mönstermatchning med | . Den använder villkorsstyrd matchning för att avgöra om de tre första tecknen efter en ordgräns är två siffror följt av ett bindestreck. I så fall försöker den matcha ett U.S. Employer Identification Number (EIN). Annars försöker den matcha ett amerikanskt socialförsäkringsnummer (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

Mönstret \b(?(\d{2}-)\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b för reguljära uttryck tolkas enligt följande tabell:

Mönster beskrivning
\b Börja vid en ordgräns.
(?(\d{2}-) Avgör om de följande tre tecknen består av två siffror följt av ett bindestreck.
\d{2}-\d{7} Om föregående mönster matchar matchar du två siffror följt av ett bindestreck följt av sju siffror.
\d{3}-\d{2}-\d{4} Om det föregående mönstret inte matchar matchar du tre decimaltal, ett bindestreck, två decimalsiffror, ett annat bindestreck och fyra decimaler.
\b Matcha en ordgräns.

Villkorsstyrd matchning baserat på en giltig infångad grupp

Det här språkelementet försöker matcha ett av två mönster beroende på om det har matchat en angiven insamlingsgrupp. Syntaxen är:

(?(Namn ) Ja )

eller

(?(Namn ) Ja | Nej )

eller

(?(nummer ) Ja )

eller

(?(nummer ) Ja | Nej )

där namnet är namnet och talet är antalet för en insamlingsgrupp, ja är uttrycket som ska matcha om namn eller tal har en matchning, och nej är det valfria uttrycket som ska matchas om det inte gör det (om inget mönster inte anges motsvarar det ett tomt nej).

Om namnet inte motsvarar namnet på en insamlingsgrupp som används i mönstret för reguljära uttryck tolkas växlingskonstruktionen som ett uttryckstest, enligt beskrivningen i föregående avsnitt. Det innebär vanligtvis att uttrycket utvärderas till false. Om talet inte motsvarar en numrerad insamlingsgrupp som används i mönstret för reguljära uttryck genererar motorn för reguljära uttryck en ArgumentException.

Följande exempel är en variant av exemplet som visas i avsnittet Antingen/eller Mönstermatchning med | . Den använder en insamlingsgrupp med namnet n2 som består av två siffror följt av ett bindestreck. Växlingskonstruktionen testar om den här insamlingsgruppen har matchats i indatasträngen. Om den har gjort det försöker alternationskonstruktionen matcha de sista sju siffrorna i ett niosiffrigt U.S. Employer Identification Number (EIN). Om den inte har gjort det försöker den matcha ett niosiffrigt amerikanskt socialförsäkringsnummer (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

Mönstret \b(?<n2>\d{2}-)?(?(n2)\d{7}|\d{3}-\d{2}-\d{4})\b för reguljära uttryck tolkas enligt följande tabell:

Mönster beskrivning
\b Börja vid en ordgräns.
(?<n2>\d{2}-)? Matcha noll eller en förekomst av två siffror följt av ett bindestreck. Ge den här insamlingsgruppen n2namnet .
(?(n2) Testa om n2 matchades i indatasträngen.
\d{7} Om n2 matchades matchar du sju decimaler.
|\d{3}-\d{2}-\d{4} Om n2 det inte matchades matchar du tre decimaler, ett bindestreck, två decimalsiffror, ett annat bindestreck och fyra decimalsiffror.
\b Matcha en ordgräns.

En variant av det här exemplet som använder en numrerad grupp i stället för en namngiven grupp visas i följande exempel. Dess reguljära uttrycksmönster är \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

Se även