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 |
- Correspondência condicional com (?( expressão)sim|não)
- Correspondência condicional com base em um grupo capturado válido
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 n2 de 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