Construções de alternância em expressões regulares

As construções de alternância modificam uma expressão regular para permitir a correspondência condicional. O .NET suporta três construções de alternância:

Correspondência de padrões com |

Você pode usar o caractere de barra vertical (|) para corresponder a qualquer um de uma série de padrões, onde o | caractere separa cada padrão.

Como a classe de caractere positivo, o | caractere pode ser usado para corresponder a qualquer um de um número de caracteres individuais. O exemplo a seguir usa uma classe de caractere positiva e uma ou outra correspondência de padrão com o | caractere para localizar ocorrências das palavras "cinza" ou "cinza" em uma cadeia de caracteres. Neste caso, o | caractere produz uma expressão regular que é mais detalhada.

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           

A expressão regular que usa o caractere, \bgr(a|e)y\b, é interpretada | conforme mostrado na tabela a seguir:

Padrão Description
\b Comece com um limite de palavras.
gr Corresponda aos caracteres "gr".
(a|e) Corresponder a um "a" ou a um "e".
y\b Corresponda a um "y" em um limite de palavras.

O | caractere também pode ser usado para executar uma correspondência com vários caracteres ou subexpressões, que podem incluir qualquer combinação de literais de caracteres e elementos de linguagem de expressão regular. (A classe de caractere não fornece essa funcionalidade.) O exemplo a seguir usa o | caractere para extrair um número de segurança social (SSN) dos EUA, que é um número de 9 dígitos com o formato ddd-dd-dddd, ou um número de identificação do empregador dos EUA (EIN), que é um número de 9 dígitos com o formato dd-dddddddd.

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

A expressão \b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b regular é interpretada como mostrado na tabela a seguir:

Padrão Description
\b Comece com um limite de palavras.
(\d{2}-\d{7}|\d{3}-\d{2}-\d{4}) Corresponder a uma das seguintes opções: dois dígitos decimais seguidos de um hífen seguido de sete dígitos decimais; ou três dígitos decimais, um hífen, dois dígitos decimais, outro hífen e quatro dígitos decimais.
\b Termine a partida com um limite de palavras.

Correspondência condicional com uma expressão

Este elemento de linguagem tenta corresponder a um de dois padrões, dependendo se ele pode corresponder a um padrão inicial. Sua sintaxe é:

(?(expressão ) Sim )

ou

(?(expressão ) Sim | Não )

onde expressão é o padrão inicial a ser correspondido, sim é o padrão a ser correspondido se a expressão for correspondida, e não é o padrão opcional a ser correspondido se a expressão não for correspondida (se um padrão não for fornecido, é equivalente a um não vazio). O mecanismo de expressão regular trata a expressão como uma asserção de largura zero, ou seja, o mecanismo de expressão regular não avança no fluxo de entrada depois de avaliar a expressão. Portanto, essa construção é equivalente ao seguinte:

(?(?=expressão ) Sim | Não )

onde (?=expression) é uma construção de asserção de largura zero. (Para obter mais informações, consulte Construções de agrupamento.) Como o mecanismo de expressão regular interpreta a expressão como uma âncora (uma asserção de largura zero), a expressão deve ser uma asserção de largura zero (para obter mais informações, consulte Âncoras) ou uma subexpressão que também esteja contida em yes. Caso contrário, o padrão sim não pode ser correspondido.

Nota

Se a expressão for um grupo de captura nomeado ou numerado, a construção de alternância será interpretada como um teste de captura, para obter mais informações, consulte a próxima seção, Correspondência condicional baseada em um grupo de captura válido. Em outras palavras, o mecanismo de expressão regular não tenta corresponder à substring capturada, mas testa a presença ou ausência do grupo.

O exemplo a seguir é uma variação do exemplo que aparece na seção Correspondência de padrão Either/Or com | . Ele usa correspondência condicional para determinar se os três primeiros caracteres após um limite de palavra são dois dígitos seguidos por um hífen. Se estiverem, ele tenta corresponder a um Número de Identificação do Empregador (EIN) dos EUA. Caso contrário, tenta corresponder a um Número de Segurança Social (SSN) dos EUA.

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

O padrão \b(?(\d{2}-)\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b de expressão regular é interpretado como mostrado na tabela a seguir:

Padrão Description
\b Comece com um limite de palavras.
(?(\d{2}-) Determine se os próximos três caracteres consistem em dois dígitos seguidos por um hífen.
\d{2}-\d{7} Se o padrão anterior corresponder, corresponda a dois dígitos seguidos de um hífen seguido de sete dígitos.
\d{3}-\d{2}-\d{4} Se o padrão anterior não corresponder, corresponda a três dígitos decimais, um hífen, dois dígitos decimais, outro hífen e quatro dígitos decimais.
\b Corresponder a um limite de palavras.

Correspondência condicional com base em um grupo capturado válido

Esse elemento de linguagem tenta corresponder a um dos dois padrões, dependendo se ele correspondeu a um grupo de captura especificado. Sua sintaxe é:

(?(Designação ) Sim )

ou

(?(Designação ) Sim | Não )

ou

(?(número ) Sim )

ou

(?(número ) Sim | Não )

onde nome é o nome e número é o número de um grupo de captura, sim é a expressão a corresponder se nome ou número tiver uma correspondência, e não é a expressão opcional a corresponder se não tiver (se um padrão não for fornecido, é equivalente a um não vazio).

Se name não corresponder ao nome de um grupo de captura usado no padrão de expressão regular, a construção de alternância será interpretada como um teste de expressão, conforme explicado na seção anterior. Normalmente, isso significa que a expressão é avaliada como false. Se o número não corresponder a um grupo de captura numerado usado no padrão de expressão regular, o mecanismo de expressão regular lançará um ArgumentExceptionarquivo .

O exemplo a seguir é uma variação do exemplo que aparece na seção Correspondência de padrão Either/Or com | . Ele usa um grupo de captura chamado n2 que consiste em dois dígitos seguidos por um hífen. A construção de alternância testa se esse grupo de captura foi correspondido na cadeia de caracteres de entrada. Se tiver, a construção de alternância tenta corresponder aos últimos sete dígitos de um Número de Identificação do Empregador (EIN) de nove dígitos dos EUA. Se não tiver, tenta corresponder a um número de segurança social (SSN) de nove dígitos dos EUA.

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

O padrão \b(?<n2>\d{2}-)?(?(n2)\d{7}|\d{3}-\d{2}-\d{4})\b de expressão regular é interpretado como mostrado na tabela a seguir:

Padrão Description
\b Comece com um limite de palavras.
(?<n2>\d{2}-)? Corresponder a zero ou uma ocorrência de dois dígitos seguidos de um hífen. Nomeie este grupo n2de captura .
(?(n2) Teste se n2 foi correspondido na cadeia de caracteres de entrada.
\d{7} Se n2 foi correspondido, corresponda a sete dígitos decimais.
|\d{3}-\d{2}-\d{4} Se n2 não foi correspondido, corresponda a três dígitos decimais, um hífen, dois dígitos decimais, outro hífen e quatro dígitos decimais.
\b Corresponder a um limite de palavras.

Uma variação deste exemplo que usa um grupo numerado em vez de um grupo nomeado é mostrada no exemplo a seguir. Seu padrão de expressão regular é \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

Consulte também