Construtores de alternância em expressões regulares
Os constructos de alternância modificam uma expressão regular para permitir uma correspondência condicional ou do tipo um/ou outro. O .NET dá suporte a três constructos de alternância:
- Correspondência de padrão com |
- Correspondência condicional com (?(expression)yes|no)
- Correspondência condicional com base em um grupo capturado válido
Correspondência de padrão com |
Você pode usar o caractere de barra vertical (|
) para corresponder a qualquer um de uma série de padrões, no qual o caractere |
separa cada padrão.
Como a classe de caracteres positivos, o caractere |
pode ser usado para corresponder a qualquer um de vários caracteres únicos. O exemplo a seguir usa uma classe de caracteres positivos e um padrão do tipo um/ou outro correspondendo ao caractere |
para localizar ocorrências das palavras “gray” ou “grey” em uma cadeia de caracteres. Nesse 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 | Descrição |
---|---|
\b |
Iniciar em um limite de palavra. |
gr |
Corresponder aos caracteres "gr". |
(a|e) |
Corresponder a um "a" ou "e". |
y\b |
Corresponder a um “y” em um limite de palavra. |
O caractere |
também pode ser usado para executar uma correspondência do tipo um/ou outro 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 oferece essa funcionalidade.) O exemplo a seguir usa o caractere |
para extrair um SSN (Número de Segurança Social) dos EUA, que é um número de 9 dígitos com o formato ddd-dd-dddd, ou um EIN (Número de Identificação do Empregador) dos EUA, que é um número de 9 dígitos com o formato 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
A expressão regular \b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b
é interpretada conforme mostrado na tabela a seguir:
Padrão | Descrição |
---|---|
\b |
Iniciar em um limite de palavra. |
(\d{2}-\d{7}|\d{3}-\d{2}-\d{4}) |
Corresponde a uma das seguintes opções: dois dígitos decimais seguidos por um hífen seguido por 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 |
Termina a correspondência em um limite de palavra. |
Correspondência condicional com uma expressão
Este elemento de linguagem tenta corresponder a um dos dois padrões dependendo de se ele pode corresponder a um padrão inicial. Sua sintaxe é:
(?(
expressão )
sim )
or
(?(
expressão )
sim |
não )
em que expression é o padrão inicial para correspondência, yes é o padrão para correspondência se expression for correspondida e no é o padrão opcional para correspondência se expression não for correspondida (se um padrão no não for fornecido, ele é equivalente a um no vazio). O mecanismo de expressões regulares trata a expressão como uma asserção de largura zero, isto é, o mecanismo de expressões regulares não avança no fluxo de entrada após avaliar a expressão. Portanto, esse constructo é equivalente ao seguinte:
(?(?=
expressão )
sim |
não )
em que (?=
expression)
é um constructo de asserção de largura zero. (Para mais informações, consulte Constructo de agrupamento.) Como o mecanismo de expressões regulares interpreta a expressão como uma âncora (uma asserção de largura zero), a expressão precisa ser uma asserção de largura zero (para obter mais informações, confira Âncoras) ou uma subexpressão que também está contida em sim. Caso contrário, o padrão sim não pode ser correspondido.
Observação
Se expression for um grupo de captura nomeado ou numerado, o constructo de alternância é interpretado como um teste de captura. Para obter mais informações, confira Correspondência condicional com base em um grupo capturado válido. Em outras palavras, o mecanismo de expressões regulares não tenta corresponder a subcadeia de caracteres capturada, mas em vez disso, testa a presença ou ausência do grupo.
O exemplo a seguir é uma variação do exemplo que aparece na seção E/Ou Correspondência de Padrões com |. Ele usa a 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 forem, ele tentará corresponder a um EIN (Número de Identificação do Empregador) dos EUA. Caso contrário, ele tenta corresponder a um SSN (Número de Segurança Social) 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 de expressão regular \b(?(\d{2}-)\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b
é interpretado conforme mostrado na tabela a seguir:
Padrão | Descrição |
---|---|
\b |
Iniciar em um limite de palavra. |
(?(\d{2}-) |
Determinar se os próximos três caracteres são compostos por dois dígitos seguidos por um hífen. |
\d{2}-\d{7} |
Se o padrão anterior corresponder, corresponder a dois dígitos seguidos por um hífen seguido por sete dígitos. |
\d{3}-\d{2}-\d{4} |
Se o padrão anterior não corresponder, corresponder 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 palavra. |
Correspondência condicional com base em um grupo capturado válido
Este elemento de linguagem tenta corresponder a um dos dois padrões dependendo de se ele correspondeu a um grupo de captura especificado. Sua sintaxe é:
(?(
nome )
sim )
or
(?(
nome )
sim |
não )
or
(?(
número )
sim )
or
(?(
número )
sim |
não )
em que name é o nome e number é o número de um grupo de captura, yes é a expressão para correspondência se name ou number tiver uma correspondência e no for a expressão opcional para correspondência se não houver uma (se um padrão no não for fornecido, ele é equivalente a um no vazio).
Se name não corresponder ao nome de um grupo de captura que é usado no padrão de expressão regular, o constructo de alternância será interpretado como teste de expressão, conforme explicado na seção anterior. Normalmente, isso significa que expression é avaliada como false
. Se number não corresponder a um grupo de captura numerado que é usado no padrão de expressão regular, o mecanismo de expressões regulares gerará um ArgumentException.
O exemplo a seguir é uma variação do exemplo que aparece na seção E/Ou Correspondência de Padrões com |. Ele usa um grupo de captura chamado n2
que consiste em dois dígitos seguidos por um hífen. O constructo de alternância testa se este grupo de captura foi correspondido na cadeia de caracteres de entrada. Em caso afirmativo, o constructo de alternância tenta corresponder aos sete últimos dígitos de um EIN (Número de Identificação do Empregador) dos EUA. Caso contrário, ele tenta corresponder a um SSN (Número de Segurança Social) dos EUA de 9 dígitos.
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 de expressão regular \b(?<n2>\d{2}-)?(?(n2)\d{7}|\d{3}-\d{2}-\d{4})\b
é interpretado conforme mostrado na tabela a seguir:
Padrão | Descrição |
---|---|
\b |
Iniciar em um limite de palavra. |
(?<n2>\d{2}-)? |
Corresponder a zero ou uma ocorrência de dois dígitos seguidos por um hífen. Atribua um nome ao grupo de captura n2 . |
(?(n2) |
Testar se n2 foi correspondido na cadeia de caracteres de entrada. |
\d{7} |
Se n2 tiver sido correspondido, corresponder a sete dígitos decimais. |
|\d{3}-\d{2}-\d{4} |
Se n2 não tiver sido correspondido, corresponder 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 palavra. |
Uma variação desse exemplo que usa um grupo numerado em vez de um grupo nomeado é mostrada no exemplo a seguir. O padrão da 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