Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
As construções de agrupamento delineiam as subexpressões de uma expressão regular e capturam as subcadeias de uma cadeia de caracteres de entrada. Você pode usar construções de agrupamento para fazer isto:
- Faz a correspondência de uma subexpressão que é repetida na cadeia de caracteres de entrada.
- Aplicar um quantificador a uma subexpressão com diversos elementos de linguagem de expressão regular. Para saber mais sobre quantificadores, confira Quantificadores.
- Inclui uma subexpressão na cadeia de caracteres retornada pelos métodos Regex.Replace e Match.Result.
- Recupere subexpressões individuais da propriedade Match.Groups e processe-as separadamente do texto correspondente como um todo.
A tabela a seguir lista os construtos de agrupamento com suporte do mecanismo de expressões regulares .NET e indica se são de captura ou não.
| Estrutura de agrupamento | Captura ou não captura |
|---|---|
| Subexpressões correspondentes | Capturando |
| Subexpressões correspondentes nomeadas | Capturando |
| Definições de grupo de balanceamento | Capturando |
| Grupos de não captura | Não captura |
| Opções de grupo | Não captura |
| Asserções de antecipação positiva de largura zero | Não captura |
| Asserções de antevisão negativa de largura zero | Não captura |
| Afirmações de lookbehind positivas de largura zero | Não captura |
| Asserções lookbehind negativas de largura zero | Não captura |
| Grupos atômicos | Não captura |
Para saber mais sobre grupos e modelos de objetos de expressão regular, veja Constructos de agrupamento e objetos de expressão regular.
Subexpressões correspondentes
O constructo de agrupamento a seguir captura uma subexpressão correspondente:
(
subexpressão)
Aqui, subexpressão é qualquer padrão de expressão regular válido. As capturas que usam parênteses são numeradas automaticamente, da esquerda para a direita, com base na ordem do parêntese de abertura na expressão regular, começando em 1. No entanto, grupos de captura nomeados sempre são ordenados por último, após grupos de captura não nomeados. A captura que recebe o número 0 é o texto que coincide com todo o padrão da expressão regular.
Observação
Por padrão, o elemento da linguagem (subexpression) captura a subexpressão correspondente. Porém, se o parâmetro RegexOptions em um método de correspondência de padrão de expressão regular inclui o sinalizador RegexOptions.ExplicitCapture ou se a opção n é aplicada a essa subexpressão (consulte Opções de grupo mais adiante neste artigo), não se captura a subexpressão coincidente.
Você pode acessar os grupos capturados de quatro formas:
Usando o constructo de referência inversa na expressão regular. A subexpressão correspondente é referenciada na mesma expressão regular usando a sintaxe
\number, em que number é o número ordinal da subexpressão capturada.Usando o constructo de referência inversa nomeado na expressão regular. A subexpressão coincidente é referenciada na mesma expressão regular usando a sintaxe
\k<name>, em que name é o nome de um grupo de captura, ou\k<number>, em que number é o número ordinal de um grupo de captura. O grupo de captura tem um nome padrão que é idêntico a seu número ordinal. Para saber mais, confira Subexpressões coincidentes nomeadas mais adiante neste tópico.Ao usar a sequência de substituição
$number em uma chamada de método Regex.Replace ou Match.Result, em que number é o número ordinal da subexpressão capturada.Usando de forma programática o objeto GroupCollection retornado pela propriedade Match.Groups. O membro na posição zero da coleção representa a correspondência total da expressão regular. Cada membro subsequente representa uma subexpressão correspondente. Para obter mais informações, veja a seção Construções de agrupamento e objetos de expressão regular.
O exemplo a seguir mostra uma expressão regular que identifica palavras duplicadas no texto. Os dois grupos de captura do padrão da expressão regular representam as duas ocorrências da palavra duplicada. A segunda instância é capturada para relatar a posição inicial na cadeia de caracteres de entrada.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"(\w+)\s(\1)\W";
string input = "He said that that was the the correct answer.";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
Console.WriteLine($"Duplicate '{match.Groups[1].Value}' found at positions {match.Groups[1].Index} and {match.Groups[2].Index}.");
}
}
// The example displays the following output:
// Duplicate 'that' found at positions 8 and 13.
// Duplicate 'the' found at positions 22 and 26.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "(\w+)\s(\1)\W"
Dim input As String = "He said that that was the the correct answer."
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
Console.WriteLine("Duplicate '{0}' found at positions {1} and {2}.", _
match.Groups(1).Value, match.Groups(1).Index, match.Groups(2).Index)
Next
End Sub
End Module
' The example displays the following output:
' Duplicate 'that' found at positions 8 and 13.
' Duplicate 'the' found at positions 22 and 26.
Este é o padrão da expressão regular:
(\w+)\s(\1)\W
A tabela a seguir mostra como o padrão da expressão regular é interpretado.
| Padrão | Descrição |
|---|---|
(\w+) |
Fazer a correspondência a um ou mais caracteres de palavra. Este é o primeiro grupo de captura. |
\s |
Corresponde a um caractere de espaço em branco. |
(\1) |
Corresponde à cadeia de caracteres no primeiro grupo capturado. Este é o segundo grupo de captura. O exemplo o atribui a um grupo capturado para que seja possível recuperar a posição inicial da palavra duplicada da propriedade Match.Index. |
\W |
Corresponder a caracteres não alfanuméricos, incluindo espaços em branco e pontuação. Isso impede a correspondência de um padrão de expressão regular com uma expressão que começa com a palavra do primeiro grupo capturado. |
Subexpressões correspondentes nomeadas
O constructo de agrupamento a seguir captura uma subexpressão correspondente e permite acessá-la usando seu nome ou número:
(?<name>subexpression)
ou:
(?'name'subexpression)
Aqui, nome é um nome de grupo válido e subexpressão é qualquer padrão de expressão regular válido. name não deve conter caracteres de pontuação nem começar com um número.
Observação
Se o parâmetro RegexOptions de um padrão de expressão regular que corresponde ao método inclui o sinalizador RegexOptions.ExplicitCapture ou se a opção n é aplicada a essa subexpressão (consulte Opções de grupo mais adiante neste tópico), a única forma de capturar uma subexpressão é atribuir nomes explícitos a grupos de captura.
Você pode acessar grupos capturados nomeados destas formas:
Usando o constructo de referência inversa nomeado na expressão regular. A subexpressão coincidente é referenciada na mesma expressão regular usando a sintaxe
\k<name>, em que name é o nome da subexpressão capturada.Usando o constructo de referência inversa na expressão regular. A subexpressão correspondente é referenciada na mesma expressão regular usando a sintaxe
\number, em que number é o número ordinal da subexpressão capturada. As subexpressões correspondentes nomeadas são numeradas em ordem de sequência, da esquerda da direita, após as subexpressões correspondentes.Ao usar a sequência de substituição
${name}em uma chamada de método Regex.Replace ou Match.Result, em que name é o nome da subexpressão capturada.Ao usar a sequência de substituição
$number em uma chamada de método Regex.Replace ou Match.Result, em que number é o número ordinal da subexpressão capturada.Usando de forma programática o objeto GroupCollection retornado pela propriedade Match.Groups. O membro na posição zero da coleção representa a correspondência inteira da expressão regular. Cada membro subsequente representa uma subexpressão correspondente. Os grupos capturados nomeados são armazenados na coleção depois dos grupos capturados numerados.
De forma programática, ao fornecer o nome da subexpressão ao indexador do objeto GroupCollection (no C#) ou a sua propriedade Item[] (no Visual Basic).
Um padrão de expressão regular simples mostra como os grupos numerados (sem nome) e nomeados podem ser usados como referência de forma programática ou usando sintaxe de linguagem de expressão regular. A expressão regular ((?<One>abc)\d+)?(?<Two>xyz)(.*) gera os seguintes grupos de captura por número e nome. O primeiro grupo de captura (o número 0) sempre faz referência a todo o padrão. (Os grupos nomeados sempre são ordenados por último.)
| Número | Nome | Padrão |
|---|---|---|
| 0 | 0 (nome padrão) | ((?<One>abc)\d+)?(?<Two>xyz)(.*) |
| 1 | 1 (nome padrão) | ((?<One>abc)\d+) |
| 2 | 2 (nome padrão) | (.*) |
| 3 | Um | (?<One>abc) |
| 4 | Dois | (?<Two>xyz) |
O exemplo a seguir mostra uma expressão regular que identifica palavras duplicadas e a palavra que aparece logo na sequência. O padrão da expressão regular define duas subexpressões nomeadas: duplicateWord, que representa a palavra duplicada e nextWord, que representa a palavra que aparece logo na sequência.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"(?<duplicateWord>\w+)\s\k<duplicateWord>\W(?<nextWord>\w+)";
string input = "He said that that was the the correct answer.";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
Console.WriteLine($"A duplicate '{match.Groups["duplicateWord"].Value}' at position {match.Groups["duplicateWord"].Index} is followed by '{match.Groups["nextWord"].Value}'.");
}
}
// The example displays the following output:
// A duplicate 'that' at position 8 is followed by 'was'.
// A duplicate 'the' at position 22 is followed by 'correct'.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "(?<duplicateWord>\w+)\s\k<duplicateWord>\W(?<nextWord>\w+)"
Dim input As String = "He said that that was the the correct answer."
Console.WriteLine(Regex.Matches(input, pattern, RegexOptions.IgnoreCase).Count)
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
Console.WriteLine("A duplicate '{0}' at position {1} is followed by '{2}'.", _
match.Groups("duplicateWord").Value, match.Groups("duplicateWord").Index, _
match.Groups("nextWord").Value)
Next
End Sub
End Module
' The example displays the following output:
' A duplicate 'that' at position 8 is followed by 'was'.
' A duplicate 'the' at position 22 is followed by 'correct'.
Este é o padrão da expressão regular:
(?<duplicateWord>\w+)\s\k<duplicateWord>\W(?<nextWord>\w+)
A tabela a seguir mostra como a expressão regular é interpretada.
| Padrão | Descrição |
|---|---|
(?<duplicateWord>\w+) |
Fazer a correspondência a um ou mais caracteres de palavra. Atribua um nome ao grupo de captura duplicateWord. |
\s |
Corresponde a um caractere de espaço em branco. |
\k<duplicateWord> |
Estabeleça a correspondência da cadeia de caracteres do grupo de captura chamado duplicateWord. |
\W |
Corresponda a um caractere que não compõe palavra, incluindo espaço em branco e pontuação. Isso impede a correspondência de um padrão de expressão regular com uma expressão que começa com a palavra do primeiro grupo capturado. |
(?<nextWord>\w+) |
Fazer a correspondência a um ou mais caracteres de palavra. Atribua um nome ao grupo de captura nextWord. |
O nome de um grupo pode ser repetido em uma expressão regular. Por exemplo, é possível que mais de um grupo seja nomeado como digit, como mostra o exemplo a seguir. No caso de nomes duplicados, o valor do objeto Group é determinado pela última captura bem-sucedida na cadeia de caracteres de entrada. Além disso, a CaptureCollection é preenchida com informações sobre cada captura exatamente como seria se o nome do grupo não fosse duplicado.
No exemplo a seguir, a expressão regular \D+(?<digit>\d+)\D+(?<digit>\d+)? inclui duas ocorrências de um grupo chamado digit. O primeiro grupo chamado digit captura um ou mais caracteres de dígito. O segundo grupo chamado digit captura zero ou uma ocorrência de um ou mais caracteres de dígito. Como a saída do exemplo apresentado mostra, se o segundo grupo de captura corresponder ao texto com êxito, o valor desse texto definirá o valor do objeto Group. Se o segundo grupo de captura não corresponder à cadeia de caracteres de entrada, o valor da última correspondência bem-sucedida definirá o valor do objeto Group.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
String pattern = @"\D+(?<digit>\d+)\D+(?<digit>\d+)?";
String[] inputs = { "abc123def456", "abc123def" };
foreach (var input in inputs) {
Match m = Regex.Match(input, pattern);
if (m.Success) {
Console.WriteLine($"Match: {m.Value}");
for (int grpCtr = 1; grpCtr < m.Groups.Count; grpCtr++) {
Group grp = m.Groups[grpCtr];
Console.WriteLine($"Group {grpCtr}: {grp.Value}");
for (int capCtr = 0; capCtr < grp.Captures.Count; capCtr++)
Console.WriteLine($" Capture {capCtr}: {grp.Captures[capCtr].Value}");
}
}
else {
Console.WriteLine("The match failed.");
}
Console.WriteLine();
}
}
}
// The example displays the following output:
// Match: abc123def456
// Group 1: 456
// Capture 0: 123
// Capture 1: 456
//
// Match: abc123def
// Group 1: 123
// Capture 0: 123
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\D+(?<digit>\d+)\D+(?<digit>\d+)?"
Dim inputs() As String = {"abc123def456", "abc123def"}
For Each input As String In inputs
Dim m As Match = Regex.Match(input, pattern)
If m.Success Then
Console.WriteLine("Match: {0}", m.Value)
For grpCtr As Integer = 1 to m.Groups.Count - 1
Dim grp As Group = m.Groups(grpCtr)
Console.WriteLine("Group {0}: {1}", grpCtr, grp.Value)
For capCtr As Integer = 0 To grp.Captures.Count - 1
Console.WriteLine(" Capture {0}: {1}", capCtr,
grp.Captures(capCtr).Value)
Next
Next
Else
Console.WriteLine("The match failed.")
End If
Console.WriteLine()
Next
End Sub
End Module
' The example displays the following output:
' Match: abc123def456
' Group 1: 456
' Capture 0: 123
' Capture 1: 456
'
' Match: abc123def
' Group 1: 123
' Capture 0: 123
A tabela a seguir mostra como a expressão regular é interpretada.
| Padrão | Descrição |
|---|---|
\D+ |
Corresponder a um ou mais caracteres de dígito não decimal. |
(?<digit>\d+) |
Corresponda a um ou mais dígitos decimais. Atribuir a partida ao grupo chamado digit. |
\D+ |
Associar um ou mais caracteres de dígito não decimal. |
(?<digit>\d+)? |
Corresponde a zero ou uma ocorrência de um ou mais caracteres de dígito decimal. Atribuir a correspondência ao grupo chamado digit. |
Definições de grupo de balanceamento
Uma definição de grupo de balanceamento exclui a definição de um grupo definido anteriormente e armazena, no grupo atual, o intervalo entre o grupo definido anteriormente e o atual. Esse constructo de agrupamento tem o seguinte formato:
(?<name1-name2>subexpression)
ou:
(?'name1-name2' subexpression)
Aqui, name1 é o grupo atual (opcional), name2 é um grupo definido anteriormente e subexpressão é qualquer padrão de expressão regular válido. A definição de grupo de balanceamento exclui a definição de name2 e armazena o intervalo entre name2 e name1 em name1. Se nenhum grupo name2 for definido, a busca retrocede. Como a exclusão da última definição de name2 revela a definição anterior de name2, essa construção permite que você use a pilha de capturas para o grupo name2 como um contador, a fim de registrar construções aninhadas, como parênteses e colchetes.
A definição de grupo de balanceamento usa name2 como pilha. O caractere inicial de cada construto aninhado é colocado em seu grupo e na Group.Captures coleção correspondente. Quando o caractere de fechamento é correspondido, seu caractere de abertura correspondente é removido do grupo e a coleção Captures diminui em uma unidade. Após todos os caracteres de abertura e fechamento das construções aninhadas serem correspondidos, name2 fica vazio.
Observação
Depois de modificar a expressão regular do exemplo a seguir para usar o caractere de abertura e fechamento adequado de um constructo aninhado, você pode usá-lo para gerenciar a maioria dos constructo aninhados, como expressões matemáticas ou linhas do código do programa que incluem diversas chamadas de método aninhado.
O exemplo a seguir usa uma definição de grupo de equilíbrio para fazer a correspondência entre os colchetes angulares esquerdo e direito (<>) em uma string de entrada. O exemplo define dois grupos nomeados, Open e Close, que são usados como pilha para acompanhar a correspondência entre esses sinais. Cada sinal de menor capturado é enviado para a coleção de capturas do grupo Open e cada sinal de maior capturado é enviado para a coleção de capturas do grupo Close. A definição do grupo de balanceamento assegura que há um sinal de maior para cada sinal de menor. Caso não haja, o subpadrão final (?(Open)(?!)) será avaliado somente se o grupo Open não estiver vazio e, portanto, se todas as construções aninhadas não tiverem sido fechadas. Se o subpadrão final for avaliado, a correspondência falha, porque o subpadrão (?!) é uma asserção lookahead negativa de largura zero que sempre falha.
using System;
using System.Text.RegularExpressions;
class Example
{
public static void Main()
{
string pattern = "^[^<>]*" +
"(" +
"((?'Open'<)[^<>]*)+" +
"((?'Close-Open'>)[^<>]*)+" +
")*" +
"(?(Open)(?!))$";
string input = "<abc><mno<xyz>>";
Match m = Regex.Match(input, pattern);
if (m.Success == true)
{
Console.WriteLine($"Input: \"{input}\" \nMatch: \"{m}\"");
int grpCtr = 0;
foreach (Group grp in m.Groups)
{
Console.WriteLine($" Group {grpCtr}: {grp.Value}");
grpCtr++;
int capCtr = 0;
foreach (Capture cap in grp.Captures)
{
Console.WriteLine($" Capture {capCtr}: {cap.Value}");
capCtr++;
}
}
}
else
{
Console.WriteLine("Match failed.");
}
}
}
// The example displays the following output:
// Input: "<abc><mno<xyz>>"
// Match: "<abc><mno<xyz>>"
// Group 0: <abc><mno<xyz>>
// Capture 0: <abc><mno<xyz>>
// Group 1: <mno<xyz>>
// Capture 0: <abc>
// Capture 1: <mno<xyz>>
// Group 2: <xyz
// Capture 0: <abc
// Capture 1: <mno
// Capture 2: <xyz
// Group 3: >
// Capture 0: >
// Capture 1: >
// Capture 2: >
// Group 4:
// Group 5: mno<xyz>
// Capture 0: abc
// Capture 1: xyz
// Capture 2: mno<xyz>
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "^[^<>]*" & _
"(" + "((?'Open'<)[^<>]*)+" & _
"((?'Close-Open'>)[^<>]*)+" + ")*" & _
"(?(Open)(?!))$"
Dim input As String = "<abc><mno<xyz>>"
Dim rgx AS New Regex(pattern) '
Dim m As Match = Regex.Match(input, pattern)
If m.Success Then
Console.WriteLine("Input: ""{0}"" " & vbCrLf & "Match: ""{1}""", _
input, m)
Dim grpCtr As Integer = 0
For Each grp As Group In m.Groups
Console.WriteLine(" Group {0}: {1}", grpCtr, grp.Value)
grpCtr += 1
Dim capCtr As Integer = 0
For Each cap As Capture In grp.Captures
Console.WriteLine(" Capture {0}: {1}", capCtr, cap.Value)
capCtr += 1
Next
Next
Else
Console.WriteLine("Match failed.")
End If
End Sub
End Module
' The example displays the following output:
' Input: "<abc><mno<xyz>>"
' Match: "<abc><mno<xyz>>"
' Group 0: <abc><mno<xyz>>
' Capture 0: <abc><mno<xyz>>
' Group 1: <mno<xyz>>
' Capture 0: <abc>
' Capture 1: <mno<xyz>>
' Group 2: <xyz
' Capture 0: <abc
' Capture 1: <mno
' Capture 2: <xyz
' Group 3: >
' Capture 0: >
' Capture 1: >
' Capture 2: >
' Group 4:
' Group 5: mno<xyz>
' Capture 0: abc
' Capture 1: xyz
' Capture 2: mno<xyz>
O padrão da expressão regular é:
^[^<>]*(((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)*(?(Open)(?!))$
A expressão regular é interpretada da seguinte forma:
| Padrão | Descrição |
|---|---|
^ |
Inicie no início da cadeia de caracteres. |
[^<>]* |
Corresponde a zero ou mais caracteres que não são colchetes angulares esquerdo ou direito. |
(?'Open'<) |
Corresponder a um colchete angular esquerdo e atribuí-lo a um grupo nomeado Open. |
[^<>]* |
Corresponde a zero ou mais caracteres que não são sinais de menor ou de maior. |
((?'Open'<)[^<>]*)+ |
Corresponde a uma ou mais ocorrências de um sinal de menor, seguidas por zero ou mais caracteres que não sejam sinais de menor e de maior. Este é o segundo grupo de captura. |
(?'Close-Open'>) |
Corresponde a um colchete angular direito, atribui a subcadeia de caracteres entre o grupo Open e o grupo atual ao grupo Close, e exclui a definição do grupo Open. |
[^<>]* |
Corresponde a zero ou mais ocorrências de qualquer caractere que não seja um colchete angular esquerdo ou direito. |
((?'Close-Open'>)[^<>]*)+ |
Corresponde a uma ou mais ocorrências de sinal de menor seguidas por zero ou mais ocorrências de qualquer caractere que não seja um sinal de menor ou maior. Ao estabelecer a correspondência de um colchete angular direito, atribua a subcadeia de caracteres entre o grupo Open e o grupo atual ao grupo Close e exclua a definição do grupo Open. Este é o terceiro grupo de captura. |
(((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)* |
Corresponde a zero ou mais ocorrências do seguinte padrão: uma ou mais ocorrências de sinais de menor (<), seguidas por zero ou mais ocorrências de caracteres que não sejam sinais de ângulo, seguidas por uma ou mais ocorrências de sinais de maior (>), seguidas por zero ou mais ocorrências de caracteres que não sejam sinais de ângulo. Ao corresponder o colchete angular direito, exclua a definição do grupo Open e atribua a subcadeia entre o grupo Open e o grupo atual ao grupo Close. Este é o primeiro grupo de captura. |
(?(Open)(?!)) |
Se o grupo Open existir, interrompa a correspondência se for possível estabelecer a correspondência de uma cadeia de caracteres vazia, mas não avance a posição do motor de expressão regular na cadeia de caracteres. Trata-se de uma asserção negativa de lookahead com largura zero. Como uma cadeia de caracteres vazia está sempre implicitamente presente em uma cadeia de caracteres de entrada, essa correspondência sempre falha. A falha nessa correspondência indica que os colchetes angulares não estão balanceados. |
$ |
Corresponder ao final da cadeia de caracteres de entrada. |
A subexpressão final, (?(Open)(?!)), indica se as estruturas de aninhamento na cadeia de caracteres de entrada estão balanceadas corretamente (por exemplo, se cada sinal de menor corresponde a um sinal de maior). Ela usa a correspondência condicional com base em um grupo capturado válido; para obter mais informações, veja Construções de alternância. Se o grupo Open for definido, o mecanismo de expressão regular tenta estabelecer a correspondência da subexpressão (?!) na cadeia de caracteres de saída. O grupo Open só deve ser definido se as construções de aninhamento não estiverem balanceadas. Portanto, o padrão para correspondência na cadeia de caracteres de entrada sempre deve fazer com que a correspondência falhe. Nesse caso, (?!) é uma asserção lookahead negativa de largura zero que sempre falha, porque uma string vazia está sempre implicitamente presente na próxima posição da string de entrada.
No exemplo, o mecanismo da expressão regular avalia a cadeia de caracteres de entrada "<abc><mno<xyz>>" como mostra a tabela a seguir.
| Etapa | Padrão | Resultado |
|---|---|---|
| 1 | ^ |
Começa a correspondência no início da cadeia de caracteres de entrada |
| 2 | [^<>]* |
Procura caracteres que não sejam "<" antes do sinal de menor e não encontra correspondências. |
| 3 | (((?'Open'<) |
Corresponde ao colchete angular esquerdo em "<abc>" e o atribui ao grupo Open. |
| 4 | [^<>]* |
Corresponde a "abc". |
| 5 | )+ |
"<abc" é o valor do segundo grupo capturado. O próximo caractere na cadeia de caracteres de entrada não é um colchete angular esquerdo. Por isso, o motor de expressão regular não volta para o subpadrão (?'Open'<)[^<>]*). |
| 6 | ((?'Close-Open'>) |
Corresponde ao sinal de maior de "<abc>", atribui "abc", que é a substring entre o grupo Open e o sinal de maior, ao grupo Close, e exclui o valor atual ("<") do grupo Open, deixando-o vazio. |
| 7 | [^<>]* |
Procura caracteres que não sejam colchetes angulares depois do sinal de maior à direita; não encontra correspondências. |
| 8 | )+ |
O valor do terceiro grupo capturado é ">". O próximo caractere na cadeia de caracteres de entrada não é um colchete angular direito, então o mecanismo de expressão regular não volta para o subpadrão ((?'Close-Open'>)[^<>]*). |
| 9 | )* |
O valor do primeiro grupo capturado é "<abc>". O próximo caractere na cadeia de caracteres de entrada é um sinal de menor. Por isso, o mecanismo de expressão regular volta para o subpadrão (((?'Open'<). |
| 10 | (((?'Open'<) |
Corresponde ao sinal de menor em "<mno" e o atribui ao grupo Open. Agora, sua coleção Group.Captures tem um só valor, "<". |
| 11 | [^<>]* |
Corresponde a "mno". |
| 12 | )+ |
"<mno" é o valor do segundo grupo capturado. O próximo caractere na cadeia de caracteres de entrada é um sinal de menor. Por isso, o mecanismo de expressão regular volta para o subpadrão (?'Open'<)[^<>]*). |
| 13 | (((?'Open'<) |
Corresponde ao colchete angular esquerdo em "<xyz>" e o atribui ao grupo Open. Agora, a coleção Group.Captures do grupo Open inclui duas capturas: o sinal de menor de "<mno" e o sinal de menor de "<xyz>". |
| 14 | [^<>]* |
Corresponde a "xyz". |
| 15 | )+ |
"<xyz" é o valor do segundo grupo capturado. O próximo caractere na cadeia de caracteres de entrada não é uma caixa de ângulo esquerdo, então o mecanismo de expressão regular não volta para o subpadrão (?'Open'<)[^<>]*). |
| 16 | ((?'Close-Open'>) |
Corresponde ao colchete angular direito em "<xyz>". "xyz" atribui a subcadeia de caracteres entre o grupo Open e o sinal de maior ao grupo Close e exclui o valor atual do grupo Open. O valor da captura anterior (o símbolo de menor em "<mno") transforma-se no valor atual do grupo Open. Agora, a coleção Captures do grupo Open inclui uma só captura: o sinal de menor de "<xyz>". |
| 17 | [^<>]* |
Procura por caracteres que não sejam sinais de menor ou maior e não encontra correspondências. |
| 18 | )+ |
O valor do terceiro grupo capturado é ">". O próximo caractere na cadeia de caracteres de entrada é um colchete angular direito. Por isso, o mecanismo de expressão regular volta para o subpadrão ((?'Close-Open'>)[^<>]*). |
| 19 | ((?'Close-Open'>) |
Corresponde ao colchete angular direito final em "xyz>>", atribui "mno<xyz>" (a substring entre o grupo Open e o colchete angular direito) ao grupo Close e exclui o valor atual do grupo Open. Agora, o grupo Open está vazio. |
| 20 | [^<>]* |
Procura por caracteres que não sejam sinais de menor que ( < ) e maior que ( > ), mas não encontra correspondências. |
| 21 | )+ |
O valor do terceiro grupo capturado é ">". O próximo caractere na cadeia de caracteres de entrada não é um sinal de maior. Por isso, o mecanismo de expressão regular não volta para o subpadrão ((?'Close-Open'>)[^<>]*). |
| 22 | )* |
O valor do primeiro grupo capturado é "<mno<xyz>>". O próximo caractere na cadeia de caracteres de entrada não é uma caixa de ângulo esquerdo, então o mecanismo de expressão regular não volta para o subpadrão (((?'Open'<). |
| 23 | (?(Open)(?!)) |
O grupo Open não é definido. Por isso, não há tentativa de correspondência. |
| 24 | $ |
Corresponde ao final da cadeia de caracteres de entrada. |
Grupos de não captura
O constructo de grupo a seguir não captura a substring correspondente a uma subexpressão:
(?:subexpression)
Aqui, subexpressão é qualquer padrão de expressão regular válido. O construto de não captura de grupo geralmente é usado quando um quantificador é aplicado a um grupo, mas as subcadeias de caracteres capturadas pelo grupo não têm interesse.
Observação
Se uma expressão regular inclui construtos de agrupamento aninhados, um grupo não capturador externo não se aplica aos construtos de agrupamento aninhados internos.
O exemplo a seguir mostra uma expressão regular que inclui grupos não capturantes. O resultado não inclui grupos capturados.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"(?:\b(?:\w+)\W*)+\.";
string input = "This is a short sentence.";
Match match = Regex.Match(input, pattern);
Console.WriteLine($"Match: {match.Value}");
for (int ctr = 1; ctr < match.Groups.Count; ctr++)
Console.WriteLine($" Group {ctr}: {match.Groups[ctr].Value}");
}
}
// The example displays the following output:
// Match: This is a short sentence.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "(?:\b(?:\w+)\W*)+\."
Dim input As String = "This is a short sentence."
Dim match As Match = Regex.Match(input, pattern)
Console.WriteLine("Match: {0}", match.Value)
For ctr As Integer = 1 To match.Groups.Count - 1
Console.WriteLine(" Group {0}: {1}", ctr, match.Groups(ctr).Value)
Next
End Sub
End Module
' The example displays the following output:
' Match: This is a short sentence.
A expressão regular (?:\b(?:\w+)\W*)+\. corresponde a uma frase terminada por um ponto. Como a expressão regular concentra-se em sentenças, e não em palavras, as construções de agrupamento são usadas apenas como quantificadores. O padrão da expressão regular é interpretado conforme a tabela a seguir.
| Padrão | Descrição |
|---|---|
\b |
Iniciar a correspondência em uma fronteira de palavra. |
(?:\w+) |
Fazer a correspondência a um ou mais caracteres de palavra. Não atribui o texto coincidente a um grupo capturado. |
\W* |
Corresponde a zero ou mais caracteres que não compõem palavras. |
(?:\b(?:\w+)\W*)+ |
Corresponde ao padrão de um ou mais caracteres de palavra iniciando em um limite de palavra, seguido por zero ou mais caracteres que não são de palavra, uma ou mais vezes. Não atribui o texto coincidente a um grupo capturado. |
\. |
Corresponder a um ponto. |
Opções de grupo
O constructo de agrupamento a seguir aplica ou desabilita as opções especificadas em uma subexpressão:
(?imnsx-imnsx:
subexpressão)
Aqui, subexpressão é qualquer padrão de expressão regular válido. Por exemplo, (?i-s:) ativa a insensibilidade a maiúsculas e desabilita o modo de linha única. Para saber mais sobre as opções embutidas que você pode especificar, veja Opções de expressões regulares.
Observação
Você pode especificar opções que se aplicam a toda uma expressão regular, em vez de a uma subexpressão, usando um construtor de classe System.Text.RegularExpressions.Regex ou método estático. Você também pode especificar opções embutidas que são aplicadas após um ponto específico de uma expressão regular, usando o constructo de linguagem (?imnsx-imnsx).
O constructo de opções de grupo não é um grupo de captura. Ou seja, embora todas as porções de uma cadeia de caracteres que são capturadas pela subexpressão sejam incluídas na correspondência, elas não são incluídas em grupos capturados, nem usadas para preencher o objeto GroupCollection.
Por exemplo, a expressão regular \b(?ix: d \w+)\s no exemplo a seguir usa opções embutidas em um constructo de agrupamento para habilitar a correspondência sem diferenciação de maiúsculas e minúsculas e ignorar os espaços em branco do padrão, ao identificar todas as palavras que começam com a letra "d". A expressão regular é definida como mostrado na tabela a seguir.
| Padrão | Descrição |
|---|---|
\b |
Iniciar a correspondência em uma fronteira de palavra. |
(?ix: d \w+) |
Usando correspondência sem distinção de maiúsculas e minúsculas e ignorando espaços em branco neste padrão, corresponde a um "d" seguido por um ou mais caracteres de palavra. |
\s |
Corresponde a um caractere de espaço em branco. |
string pattern = @"\b(?ix: d \w+)\s";
string input = "Dogs are decidedly good pets.";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine($"'{match.Value}// found at index {match.Index}.");
// The example displays the following output:
// 'Dogs // found at index 0.
// 'decidedly // found at index 9.
Dim pattern As String = "\b(?ix: d \w+)\s"
Dim input As String = "Dogs are decidedly good pets."
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("'{0}' found at index {1}.", match.Value, match.Index)
Next
' The example displays the following output:
' 'Dogs ' found at index 0.
' 'decidedly ' found at index 9.
Asserções lookahead positivas de largura zero
O constructo de agrupamento a seguir define uma asserção lookahead positiva de largura zero:
(?=
subexpressão)
Aqui, subexpressão é qualquer padrão de expressão regular. Para que a correspondência seja executada com êxito, a cadeia de caracteres de entrada deve corresponder ao padrão de expressão regular na subexpression, embora a subcadeia de caracteres com a qual a correspondência foi estabelecida não conste no resultado. A asserção de lookahead positiva de largura zero (zero-width positive lookahead assertion) não retrocede.
Geralmente, uma afirmação de antecipação positiva de largura zero é encontrada no final de um padrão de expressão regular. Isso define uma subcadeia de caracteres que deve estar presente no final da cadeia de caracteres para que seja possível estabelecer a correspondência, mas que não seja incluída na correspondência. Isso também é útil para evitar retrocessos em excesso. Você pode usar uma asserção lookahead positiva de largura zero para garantir que um grupo capturado específico comece com um texto que corresponda a um subconjunto do padrão definido para aquele grupo capturado. Por exemplo, se um grupo de captura corresponder a caracteres de palavras em sequência, você pode usar uma asserção de lookahead positivo de largura zero para que o primeiro caractere seja um caractere alfabético maiúsculo.
O exemplo a seguir usa asserção lookahead positiva de largura zero para estabelecer a correspondência da palavra que precede o verbo "is" na cadeia de caracteres de entrada.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"\b\w+(?=\sis\b)";
string[] inputs = { "The dog is a Malamute.",
"The island has beautiful birds.",
"The pitch missed home plate.",
"Sunday is a weekend day." };
foreach (string input in inputs)
{
Match match = Regex.Match(input, pattern);
if (match.Success)
Console.WriteLine($"'{match.Value}' precedes 'is'.");
else
Console.WriteLine($"'{input}' does not match the pattern.");
}
}
}
// The example displays the following output:
// 'dog' precedes 'is'.
// 'The island has beautiful birds.' does not match the pattern.
// 'The pitch missed home plate.' does not match the pattern.
// 'Sunday' precedes 'is'.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b\w+(?=\sis\b)"
Dim inputs() As String = {"The dog is a Malamute.", _
"The island has beautiful birds.", _
"The pitch missed home plate.", _
"Sunday is a weekend day."}
For Each input As String In inputs
Dim match As Match = Regex.Match(input, pattern)
If match.Success Then
Console.WriteLine("'{0}' precedes 'is'.", match.Value)
Else
Console.WriteLine("'{0}' does not match the pattern.", input)
End If
Next
End Sub
End Module
' The example displays the following output:
' 'dog' precedes 'is'.
' 'The island has beautiful birds.' does not match the pattern.
' 'The pitch missed home plate.' does not match the pattern.
' 'Sunday' precedes 'is'.
A expressão regular \b\w+(?=\sis\b) é interpretada conforme mostrado na tabela a seguir.
| Padrão | Descrição |
|---|---|
\b |
Iniciar a correspondência em uma fronteira de palavra. |
\w+ |
Fazer a correspondência a um ou mais caracteres de palavra. |
(?=\sis\b) |
Determina se os caracteres que compõem palavras são seguidos por um caractere de espaço em branco e pela cadeia de caracteres "is", que termina com um limite de palavra. Nesse caso, a correspondência ocorreu com êxito. |
Asserções lookahead negativas de largura zero
O construto de agrupamento a seguir define uma asserção de antecipação negativa de largura zero.
(?!
subexpressão)
Aqui, subexpressão é qualquer padrão de expressão regular. Para que a correspondência seja executada com êxito, a cadeia de caracteres de entrada não deve corresponder ao padrão de expressão regular na subexpression, embora a cadeia de caracteres com a qual a correspondência foi estabelecida não conste no resultado.
Geralmente, uma asserção de lookahead negativo de largura zero é usada no início ou no final de uma expressão regular. No início de uma expressão regular, é possível definir um padrão específico que não deve ser correspondido quando o início da expressão regular define um padrão semelhante, mas mais geral, a ser correspondido. Nesse caso, é frequentemente usado para limitar o retrocesso. No final de uma expressão regular, pode definir uma subexpressão que pode não ocorrer no final de uma correspondência.
O exemplo a seguir define uma expressão regular que usa uma afirmação lookahead de largura zero no início da expressão regular para corresponder a palavras que não começam com "un".
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"\b(?!un)\w+\b";
string input = "unite one unethical ethics use untie ultimate";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
Console.WriteLine(match.Value);
}
}
// The example displays the following output:
// one
// ethics
// use
// ultimate
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b(?!un)\w+\b"
Dim input As String = "unite one unethical ethics use untie ultimate"
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
Console.WriteLine(match.Value)
Next
End Sub
End Module
' The example displays the following output:
' one
' ethics
' use
' ultimate
A expressão regular \b(?!un)\w+\b é interpretada conforme mostrado na tabela a seguir.
| Padrão | Descrição |
|---|---|
\b |
Iniciar a correspondência em uma fronteira de palavra. |
(?!un) |
Determina se os dois caracteres seguintes são "un". Caso não sejam, é possível estabelecer a correspondência. |
\w+ |
Fazer a correspondência a um ou mais caracteres de palavra. |
\b |
Termina a correspondência em um limite de palavra. |
O exemplo a seguir define uma expressão regular que usa uma asserção lookahead de largura zero no final da expressão regular para fazer a correspondência de palavras que não terminam com um caractere de pontuação.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"\b\w+\b(?!\p{P})";
string input = "Disconnected, disjointed thoughts in a sentence fragment.";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine(match.Value);
}
}
// The example displays the following output:
// disjointed
// thoughts
// in
// a
// sentence
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b\w+\b(?!\p{P})"
Dim input As String = "Disconnected, disjointed thoughts in a sentence fragment."
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(match.Value)
Next
End Sub
End Module
' The example displays the following output:
' disjointed
' thoughts
' in
' a
' sentence
A expressão regular \b\w+\b(?!\p{P}) é interpretada conforme mostrado na tabela a seguir.
| Padrão | Descrição |
|---|---|
\b |
Iniciar a correspondência em uma fronteira de palavra. |
\w+ |
Fazer a correspondência a um ou mais caracteres de palavra. |
\b |
Termina a correspondência em um limite de palavra. |
\p{P}) |
Se o caractere seguinte não for um símbolo de pontuação (por exemplo, um ponto final ou uma vírgula), a correspondência tem sucesso. |
Asserções lookbehind positivas de largura zero
O constructo de agrupamento a seguir define uma asserção lookbehind positiva de largura zero:
(?<=
subexpressão)
Aqui, subexpressão é qualquer padrão de expressão regular. Para que a correspondência seja bem-sucedida, a subexpressão deve ocorrer na cadeia de entrada à esquerda da posição atual, embora subexpression não conste no resultado. A asserção lookbehind positiva de largura zero não retrocede.
As asserções lookbehind positivas de largura zero geralmente são usadas no início de expressões regulares. O padrão que elas definem é uma pré-condição para uma correspondência, embora não faça parte do resultado da correspondência.
Por exemplo, o exemplo a seguir corresponde aos dois últimos dígitos do ano no século XXI (ou seja, requer que os dígitos "20" precedam a sequência correspondente).
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string input = "2010 1999 1861 2140 2009";
string pattern = @"(?<=\b20)\d{2}\b";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine(match.Value);
}
}
// The example displays the following output:
// 10
// 09
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "2010 1999 1861 2140 2009"
Dim pattern As String = "(?<=\b20)\d{2}\b"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(match.Value)
Next
End Sub
End Module
' The example displays the following output:
' 10
' 09
O padrão da expressão regular (?<=\b20)\d{2}\b é interpretado conforme mostrado na tabela a seguir.
| Padrão | Descrição |
|---|---|
\d{2} |
Encontre dois dígitos decimais. |
(?<=\b20) |
Continue a correspondência se os dois dígitos decimais estiverem precedidos por "20" em um limite de palavra. |
\b |
Termina a correspondência em um limite de palavra. |
As asserções lookbehind positivas de largura zero também são usadas para limitar o retrocesso quando o último caractere de um grupo capturado precisar ser um subconjunto de caracteres que corresponde ao padrão de expressão regular desse grupo. Por exemplo, se um grupo captura todos os caracteres de palavras em sequência, você pode usar uma asserção lookbehind positiva de largura zero para exigir que o último caractere seja alfabético.
Asserções de lookbehind negativas de largura zero
O constructo de agrupamento a seguir define uma asserção lookbehind negativa de largura zero:
(?<!
subexpressão)
Aqui, subexpressão é qualquer padrão de expressão regular. Para que a correspondência seja bem-sucedida, a subexpressão não deve ocorrer na cadeia de caracteres de entrada à esquerda da posição atual. No entanto, todas as subcadeias de caracteres que não corresponderem a subexpression, não serão incluídas no resultado.
As asserções lookbehind negativas de largura zero geralmente são usadas no início de expressões regulares. O padrão definido por elas elimina uma correspondência na cadeia de caracteres seguinte. Eles também são usados para limitar o retrocesso quando o último caractere ou caracteres de um grupo capturado não deve ser um ou mais dos caracteres que correspondem ao padrão de expressão regular desse grupo. Por exemplo, se um grupo captura todos os caracteres de palavras em sequência, você pode usar uma afirmação lookbehind positiva de largura zero para requerer que o último caractere não seja um sublinhado (_).
O exemplo a seguir corresponde à data para qualquer dia da semana que não é um fim de semana, ou seja, que não é nem sábado nem domingo.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string[] dates = { "Monday February 1, 2010",
"Wednesday February 3, 2010",
"Saturday February 6, 2010",
"Sunday February 7, 2010",
"Monday, February 8, 2010" };
string pattern = @"(?<!(Saturday|Sunday) )\b\w+ \d{1,2}, \d{4}\b";
foreach (string dateValue in dates)
{
Match match = Regex.Match(dateValue, pattern);
if (match.Success)
Console.WriteLine(match.Value);
}
}
}
// The example displays the following output:
// February 1, 2010
// February 3, 2010
// February 8, 2010
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim dates() As String = {"Monday February 1, 2010", _
"Wednesday February 3, 2010", _
"Saturday February 6, 2010", _
"Sunday February 7, 2010", _
"Monday, February 8, 2010"}
Dim pattern As String = "(?<!(Saturday|Sunday) )\b\w+ \d{1,2}, \d{4}\b"
For Each dateValue As String In dates
Dim match As Match = Regex.Match(dateValue, pattern)
If match.Success Then
Console.WriteLine(match.Value)
End If
Next
End Sub
End Module
' The example displays the following output:
' February 1, 2010
' February 3, 2010
' February 8, 2010
O padrão da expressão regular (?<!(Saturday|Sunday) )\b\w+ \d{1,2}, \d{4}\b é interpretado conforme mostrado na tabela a seguir.
| Padrão | Descrição |
|---|---|
\b |
Iniciar a correspondência em uma fronteira de palavra. |
\w+ |
Corresponde a um ou mais caracteres de palavra seguidos por um caractere de espaço em branco. |
\d{1,2}, |
Corresponde a um ou dois dígitos decimais seguidos por um caractere de espaço em branco e uma vírgula. |
\d{4}\b |
Corresponde a quatro dígitos decimais e encerra a correspondência em um limite de palavra. |
(?<!(Saturday|Sunday) ) |
Se a correspondência for precedida por algo diferente das cadeias de caracteres "Sábado" ou "Domingo" seguidas por um espaço, a correspondência é bem-sucedida. |
Grupos atômicos
O seguinte constructo de agrupamento representa um grupo atômico (conhecido em alguns outros mecanismos de expressão regulares como uma subexpressão sem retrocesso, uma subexpressão atômica ou uma subexpressão somente uma vez):
(?>
subexpressão)
Aqui, subexpressão é qualquer padrão de expressão regular.
Geralmente, se uma expressão regular incluir um padrão de correspondência opcional ou alternativo e a correspondência não for realizada com êxito, o mecanismo da expressão regular pode ramificar em diversas orientações para estabelecer a correspondência entre uma cadeia de caracteres de entrada e um padrão. Se a correspondência não for encontrada na primeira ramificação, o mecanismo da expressão regular pode voltar ou retroceder ao ponto da primeira correspondência e tentar estabelecer a correspondência usando a segunda ramificação. Esse processo pode continuar até que todos os ramos tenham sido tentados.
O constructo de linguagem da (?>subexpression) desabilita o retrocesso. O mecanismo de expressão regular estabelece a correspondência entre o máximo de caracteres da cadeia de caracteres de entrada. Quando não for possível estabelecer outras correspondências, ele não retrocede para tentar correspondências alternativas de padrão. Ou seja, a subexpressão corresponde somente às cadeias de caracteres que poderiam corresponder somente à subexpressão. Ela não tenta fazer a correspondência de uma cadeia de caracteres com base na subexpressão em questão e nas subexpressões seguintes.
Essa opção é recomendada quando você sabe que o retrocesso não terá êxito. Evitar que o mecanismo de expressão regular faça pesquisas desnecessárias, melhora o desempenho.
O exemplo a seguir mostra como um grupo atômico modifica os resultados de uma correspondência padrão. A expressão regular de retrocesso estabelece a correspondência de diversos caracteres repetidos, seguidos por outra ocorrência do mesmo caractere de um limite de palavra, mas a expressão regular sem retrocesso não faz isso.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string[] inputs = { "cccd.", "aaad", "aaaa" };
string back = @"(\w)\1+.\b";
string noback = @"(?>(\w)\1+).\b";
foreach (string input in inputs)
{
Match match1 = Regex.Match(input, back);
Match match2 = Regex.Match(input, noback);
Console.WriteLine($"{input}: ");
Console.Write(" Backtracking : ");
if (match1.Success)
Console.WriteLine(match1.Value);
else
Console.WriteLine("No match");
Console.Write(" Nonbacktracking: ");
if (match2.Success)
Console.WriteLine(match2.Value);
else
Console.WriteLine("No match");
}
}
}
// The example displays the following output:
// cccd.:
// Backtracking : cccd
// Nonbacktracking: cccd
// aaad:
// Backtracking : aaad
// Nonbacktracking: aaad
// aaaa:
// Backtracking : aaaa
// Nonbacktracking: No match
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim inputs() As String = {"cccd.", "aaad", "aaaa"}
Dim back As String = "(\w)\1+.\b"
Dim noback As String = "(?>(\w)\1+).\b"
For Each input As String In inputs
Dim match1 As Match = Regex.Match(input, back)
Dim match2 As Match = Regex.Match(input, noback)
Console.WriteLine("{0}: ", input)
Console.Write(" Backtracking : ")
If match1.Success Then
Console.WriteLine(match1.Value)
Else
Console.WriteLine("No match")
End If
Console.Write(" Nonbacktracking: ")
If match2.Success Then
Console.WriteLine(match2.Value)
Else
Console.WriteLine("No match")
End If
Next
End Sub
End Module
' The example displays the following output:
' cccd.:
' Backtracking : cccd
' Nonbacktracking: cccd
' aaad:
' Backtracking : aaad
' Nonbacktracking: aaad
' aaaa:
' Backtracking : aaaa
' Nonbacktracking: No match
A expressão regular sem retrocesso (?>(\w)\1+).\b é definida como mostra a tabela a seguir.
| Padrão | Descrição |
|---|---|
(\w) |
Corresponda a um único caractere de palavra e atribua-o ao primeiro grupo de captura. |
\1+ |
Corresponda ao valor da primeira subcadeia capturada uma ou mais vezes. |
. |
Corresponde a qualquer caractere. |
\b |
Termine a correspondência em um limite de palavra. |
(?>(\w)\1+) |
Corresponde a uma ou mais ocorrências de um caractere de palavra duplicado, mas não executa o retrocesso para estabelecer a correspondência com o último caractere em um limite de palavra. |
Agrupando construções e objetos de expressão regulares
As subcadeias de caracteres que correspondem a um grupo de captura de expressão regular são representadas por objetos System.Text.RegularExpressions.Group, que podem ser recuperados do objeto System.Text.RegularExpressions.GroupCollection que é retornado pela propriedade Match.Groups. O objeto GroupCollection é preenchido desta forma:
- O primeiro objeto Group da coleção (o objeto de índice zero) representa a correspondência total.
- O próximo conjunto de objetos Group representa grupos de captura sem nome (numerados). Eles aparecem na ordem em que são definidos na expressão regular, da esquerda para a direita. Os valores dos índices desses grupos variam de 1 até o número de grupos de captura não nomeados presentes na coleção. (O índice de um determinado grupo é equivalente à sua referência inversa numerada. Para mais informações sobre referência inversa, confira Constructos de referência inversa.)
- O conjunto final de objetos Group representa os grupos de captura nomeados. Eles aparecem na ordem em que são definidos na expressão regular, da esquerda para a direita. O valor do índice do primeiro grupo de captura nomeado é um número maior que o índice do último grupo de captura não nomeado. Se não houver grupos de captura não nomeados na expressão regular, o valor do índice do primeiro grupo de captura nomeado será um.
Se você aplicar um quantificador a um grupo de captura, as propriedades GroupCapture.Value, Capture.Index e Capture.Length do objeto refletirão a última subcadeia de caracteres capturada por um grupo de captura. Você pode recuperar todo o conjunto de subcadeias de caracteres capturadas por grupos que têm quantificadores do objeto CaptureCollection e que são retornados pela propriedade Group.Captures.
O exemplo a seguir esclarece a relação entre os objetos Group e Capture.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"(\b(\w+)\W+)+";
string input = "This is a short sentence.";
Match match = Regex.Match(input, pattern);
Console.WriteLine($"Match: '{match.Value}'");
for (int ctr = 1; ctr < match.Groups.Count; ctr++)
{
Console.WriteLine($" Group {ctr}: '{match.Groups[ctr].Value}'");
int capCtr = 0;
foreach (Capture capture in match.Groups[ctr].Captures)
{
Console.WriteLine($" Capture {capCtr}: '{capture.Value}'");
capCtr++;
}
}
}
}
// The example displays the following output:
// Match: 'This is a short sentence.'
// Group 1: 'sentence.'
// Capture 0: 'This '
// Capture 1: 'is '
// Capture 2: 'a '
// Capture 3: 'short '
// Capture 4: 'sentence.'
// Group 2: 'sentence'
// Capture 0: 'This'
// Capture 1: 'is'
// Capture 2: 'a'
// Capture 3: 'short'
// Capture 4: 'sentence'
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "(\b(\w+)\W+)+"
Dim input As String = "This is a short sentence."
Dim match As Match = Regex.Match(input, pattern)
Console.WriteLine("Match: '{0}'", match.Value)
For ctr As Integer = 1 To match.Groups.Count - 1
Console.WriteLine(" Group {0}: '{1}'", ctr, match.Groups(ctr).Value)
Dim capCtr As Integer = 0
For Each capture As Capture In match.Groups(ctr).Captures
Console.WriteLine(" Capture {0}: '{1}'", capCtr, capture.Value)
capCtr += 1
Next
Next
End Sub
End Module
' The example displays the following output:
' Match: 'This is a short sentence.'
' Group 1: 'sentence.'
' Capture 0: 'This '
' Capture 1: 'is '
' Capture 2: 'a '
' Capture 3: 'short '
' Capture 4: 'sentence.'
' Group 2: 'sentence'
' Capture 0: 'This'
' Capture 1: 'is'
' Capture 2: 'a'
' Capture 3: 'short'
' Capture 4: 'sentence'
O padrão da expressão regular (\b(\w+)\W+)+ extrai palavras, uma a uma, da cadeia de caracteres. Ele é definido conforme mostrado na tabela a seguir.
| Padrão | Descrição |
|---|---|
\b |
Iniciar a correspondência em uma fronteira de palavra. |
(\w+) |
Fazer a correspondência a um ou mais caracteres de palavra. Juntos, esses caracteres compõem uma palavra. Este é o segundo grupo de captura. |
\W+ |
Corresponda a um ou mais caracteres que não são letras ou números. |
(\b(\w+)\W+) |
Corresponde ao padrão de um ou mais caracteres de palavra, seguido por um ou mais caracteres que não compõem palavras, repetindo esse processo uma ou mais vezes. Este é o primeiro grupo de captura. |
O segundo grupo de captura corresponde a cada palavra da oração. O primeiro grupo de captura corresponde a cada palavra juntamente com a pontuação e o espaço em branco que vêm após a palavra. O objeto Group, cujo índice é 2, fornece informações sobre o texto correspondente ao segundo grupo de captura. O conjunto completo de palavras capturadas pelo grupo de captura está disponível no objeto CaptureCollection, retornado pela propriedade Group.Captures.