Agrupando construções em expressões regulares

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 o seguinte:

  • Corresponder a uma subexpressão repetida na cadeia de caracteres de entrada.
  • Aplique um quantificador a uma subexpressão que tenha vários elementos de linguagem de expressão regular. Para obter mais informações sobre quantificadores, consulte Quantificadores.
  • Inclua uma subexpressão na cadeia de caracteres retornada pelos Regex.Replace métodos and Match.Result .
  • Recupere subexpressões individuais da Match.Groups propriedade e processe-as separadamente do texto correspondente como um todo.

A tabela a seguir lista as construções de agrupamento suportadas pelo mecanismo de expressão regular do .NET e indica se elas estão capturando ou não capturando.

Construção de agrupamento Captura ou não captura
Subexpressões correspondentes Captura
Subexpressões correspondentes nomeadas Captura
Equilibrando definições de grupo Captura
Grupos não capturados Não captura
Opções de grupo Não captura
Asserções de antecipação positivas de largura zero Não captura
Asserções prospetivas negativas de largura zero Não captura
Asserções positivas de largura zero Não captura
Asserções negativas de largura zero Não captura
Grupos atómicos Não captura

Para obter informações sobre grupos e o modelo de objeto de expressão regular, consulte Agrupando construções e objetos de expressão regular.

Subexpressões correspondentes

A construção 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 dos parênteses de abertura na expressão regular, a partir de 1. No entanto, os grupos de captura nomeados são sempre ordenados em último lugar, depois dos grupos de captura não nomeados. A captura numerada 0 é o texto correspondido por todo o padrão de expressão regular.

Nota

Por padrão, o elemento de linguagem de (subexpressão) captura a subexpressão correspondente. Mas se o RegexOptions parâmetro de um método de correspondência de padrão de expressão regular incluir o RegexOptions.ExplicitCapture sinalizador, ou se a n opção for aplicada a essa subexpressão (consulte Opções de grupo mais adiante neste artigo), a subexpressão correspondente não será capturada.

Você pode acessar os grupos capturados de quatro maneiras:

  • Usando a construção backreference dentro da expressão regular. A subexpressão correspondente é referenciada na mesma expressão regular usando o número da sintaxe\, onde number é o número ordinal da subexpressão capturada.

  • Usando a construção backreference nomeada dentro da expressão regular. A subexpressão correspondente é referenciada na mesma expressão regular usando o nome> da sintaxe\k<, onde name é o nome de um grupo de captura, ou \k<número>, onde number é o número ordinal de um grupo de captura. Um grupo de captura tem um nome padrão que é idêntico ao seu número ordinal. Para obter mais informações, consulte Subexpressões correspondentes nomeadas posteriormente neste tópico.

  • Usando a $sequência de substituição numérica em uma Regex.Replace chamada ou Match.Result método, onde number é o número ordinal da subexpressão capturada.

  • Programaticamente, usando o GroupCollection objeto retornado pela Match.Groups propriedade. O membro na posição zero na coleção representa toda a correspondência de expressão regular. Cada membro subsequente representa uma subexpressão correspondente. Para obter mais informações, consulte a seção Construções de agrupamento e objetos de expressão regular.

O exemplo a seguir ilustra uma expressão regular que identifica palavras duplicadas no texto. Os dois grupos de captura do padrão de expressão regular representam as duas ocorrências da palavra duplicada. A segunda instância é capturada para relatar sua 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 '{0}' found at positions {1} and {2}.",
                           match.Groups[1].Value, match.Groups[1].Index, 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.

O padrão de expressão regular é o seguinte:

(\w+)\s(\1)\W

A tabela a seguir mostra como o padrão de expressão regular é interpretado.

Padrão Description
(\w+) Corresponder a um ou mais caracteres de palavra. Este é o primeiro grupo de captura.
\s Corresponder a um caractere de espaço em branco.
(\1) Corresponder a cadeia de caracteres no primeiro grupo capturado. Este é o segundo grupo de captura. O exemplo o atribui a um grupo capturado para que a posição inicial da palavra duplicada possa ser recuperada da Match.Index propriedade.
\W Corresponder a um caractere sem palavras, incluindo espaço em branco e pontuação. Isso impede que o padrão de expressão regular corresponda a uma palavra que começa com a palavra do primeiro grupo capturado.

Subexpressões correspondentes nomeadas

A construção de agrupamento a seguir captura uma subexpressão correspondente e permite acessá-la por 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 e não pode começar com um número.

Nota

Se o RegexOptions parâmetro de um método de correspondência de padrão de expressão regular incluir o RegexOptions.ExplicitCapture sinalizador, ou se a n opção for aplicada a essa subexpressão (consulte Opções de grupo mais adiante neste tópico), a única maneira de capturar uma subexpressão é nomear explicitamente grupos de captura.

Você pode acessar grupos capturados nomeados das seguintes maneiras:

  • Usando a construção backreference nomeada dentro da expressão regular. A subexpressão correspondente é referenciada na mesma expressão regular usando o nome> da sintaxe\k<, onde name é o nome da subexpressão capturada.

  • Usando a construção backreference dentro da expressão regular. A subexpressão correspondente é referenciada na mesma expressão regular usando o número da sintaxe\, onde number é o número ordinal da subexpressão capturada. As subexpressões correspondentes nomeadas são numeradas consecutivamente da esquerda para a direita após as subexpressões correspondentes.

  • Usando a ${sequência de substituição de nome} em uma Regex.Replace chamada de método ou Match.Result , onde name é o nome da subexpressão capturada.

  • Usando a $sequência de substituição numérica em uma Regex.Replace chamada ou Match.Result método, onde number é o número ordinal da subexpressão capturada.

  • Programaticamente, usando o GroupCollection objeto retornado pela Match.Groups propriedade. O membro na posição zero na coleção representa toda a correspondência de expressão regular. Cada membro subsequente representa uma subexpressão correspondente. Os grupos capturados nomeados são armazenados na coleção após grupos capturados numerados.

  • Programaticamente, fornecendo o nome da subexpressão ao GroupCollection indexador do objeto (em C#) ou à sua Item[] propriedade (no Visual Basic).

Um padrão de expressão regular simples ilustra como grupos numerados (sem nome) e nomeados podem ser referenciados programaticamente ou usando sintaxe de linguagem de expressão regular. A expressão ((?<One>abc)\d+)?(?<Two>xyz)(.*) regular produz os seguintes grupos de captura por número e por nome. O primeiro grupo de captura (número 0) refere-se sempre a todo o padrão. (Os grupos nomeados são sempre 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 ilustra uma expressão regular que identifica palavras duplicadas e a palavra que se segue imediatamente a cada palavra duplicada. O padrão de expressão regular define duas subexpressões nomeadas: duplicateWord, que representa a palavra duplicada e nextWord, que representa a palavra que segue a palavra duplicada.

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 '{0}' at position {1} is followed by '{2}'.",
                           match.Groups["duplicateWord"].Value, match.Groups["duplicateWord"].Index,
                           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'.

O padrão de expressão regular é o seguinte:

(?<duplicateWord>\w+)\s\k<duplicateWord>\W(?<nextWord>\w+)

A tabela a seguir mostra como a expressão regular é interpretada.

Padrão Description
(?<duplicateWord>\w+) Corresponder a um ou mais caracteres de palavra. Nomeie este grupo duplicateWordde captura .
\s Corresponder a um caractere de espaço em branco.
\k<duplicateWord> Corresponder a cadeia de caracteres do grupo capturado chamado duplicateWord.
\W Corresponder a um caractere sem palavras, incluindo espaço em branco e pontuação. Isso impede que o padrão de expressão regular corresponda a uma palavra que começa com a palavra do primeiro grupo capturado.
(?<nextWord>\w+) Corresponder a um ou mais caracteres de palavra. Nomeie este grupo nextWordde captura .

Um nome de grupo pode ser repetido em uma expressão regular. Por exemplo, é possível que mais de um grupo seja nomeado digit, como ilustra o exemplo a seguir. No caso de nomes duplicados, o valor do objeto é determinado pela última captura bem-sucedida na cadeia de Group caracteres de entrada. Além disso, o é preenchido CaptureCollection com informações sobre cada captura, assim como seria se o nome do grupo não fosse duplicado.

No exemplo a seguir, a expressão \D+(?<digit>\d+)\D+(?<digit>\d+)? regular inclui duas ocorrências de um grupo chamado digit. O primeiro digit grupo nomeado captura um ou mais caracteres de dígitos. O segundo digit grupo nomeado captura zero ou uma ocorrência de um ou mais caracteres de dígitos. Como mostra a saída do exemplo, se o segundo grupo de captura corresponder com êxito ao texto, o valor desse texto definirá o Group valor do objeto. Se o segundo grupo de captura não corresponder à cadeia de caracteres de entrada, o valor da última correspondência bem-sucedida definirá o Group valor do objeto.

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: {0}", m.Value);
            for (int grpCtr = 1; grpCtr < m.Groups.Count; grpCtr++) {
               Group grp = m.Groups[grpCtr];
               Console.WriteLine("Group {0}: {1}", grpCtr, grp.Value);
               for (int capCtr = 0; capCtr < grp.Captures.Count; capCtr++)
                  Console.WriteLine("   Capture {0}: {1}", 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 Description
\D+ Corresponder a um ou mais caracteres de dígitos não decimais.
(?<digit>\d+) Corresponder a um ou mais caracteres de dígitos decimais. Atribua a correspondência ao digit grupo nomeado.
\D+ Corresponder a um ou mais caracteres de dígitos não decimais.
(?<digit>\d+)? Corresponder a zero ou uma ocorrência de um ou mais caracteres de dígitos decimais. Atribua a correspondência ao digit grupo nomeado.

Equilibrando definições de grupo

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 grupo atual. Esta construção 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 correspondência voltará atrás. 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 nome de grupo2como um contador para acompanhar construções aninhadas, como parênteses ou colchetes de abertura e fechamento.

A definição de grupo de balanceamento usa name2 como uma pilha. O caractere inicial de cada construção aninhada é colocado no grupo e em sua Group.Captures coleção. Quando o caractere de fechamento é correspondido, seu caractere de abertura correspondente é removido do grupo e a coleção é diminuída Captures em um. Depois que os caracteres de abertura e fechamento de todas as construções aninhadas tiverem sido correspondidos, name2 estará vazio.

Nota

Depois de modificar a expressão regular no exemplo a seguir para usar o caractere de abertura e fechamento apropriado de uma construção aninhada, você pode usá-la para manipular a maioria das construções aninhadas, como expressões matemáticas ou linhas de código de programa que incluem várias chamadas de método aninhadas.

O exemplo a seguir usa uma definição de grupo de balanceamento para corresponder aos colchetes angulares esquerdo e direito (<>) em uma cadeia de caracteres de entrada. O exemplo define dois grupos Open nomeados e , que são usados como uma pilha para rastrear pares correspondentes de colchetes Closeangulares. Cada colchete angular esquerdo capturado é empurrado para a coleção de captura do grupo, e cada colchete angular direito capturado é empurrado Open para a coleção de captura do Close grupo. A definição do grupo de balanceamento garante que haja um colchete angular direito correspondente para cada colchete angular esquerdo. Se não houver, o subpadrão final, (?(Open)(?!)), é avaliado somente se o Open grupo não estiver vazio (e, portanto, se todos os constructos aninhados não tiverem sido fechados). Se o subpadrão final for avaliado, a correspondência falhará, porque o (?!) subpadrão é uma asserção de 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: \"{0}\" \nMatch: \"{1}\"", input, m);
         int grpCtr = 0;
         foreach (Group grp in m.Groups)
         {
            Console.WriteLine("   Group {0}: {1}", grpCtr, grp.Value);
            grpCtr++;
            int capCtr = 0;
            foreach (Capture cap in grp.Captures)
            {
                Console.WriteLine("      Capture {0}: {1}", 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 de expressão regular é:

^[^<>]*(((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)*(?(Open)(?!))$

A expressão regular é interpretada da seguinte forma:

Padrão Description
^ Comece no início da cadeia de caracteres.
[^<>]* Corresponder zero ou mais caracteres que não sejam colchetes angulares esquerdo ou direito.
(?'Open'<) Corresponder a um colchete angular esquerdo e atribuí-lo a um grupo chamado Open.
[^<>]* Corresponder zero ou mais caracteres que não sejam colchetes angulares esquerdo ou direito.
((?'Open'<)[^<>]*)+ Corresponder a uma ou mais ocorrências de um colchete angular esquerdo seguido por zero ou mais caracteres que não sejam colchetes angulares esquerdo ou direito. Este é o segundo grupo de captura.
(?'Close-Open'>) Corresponder a um colchete angular reto, atribuir a substring entre o Open grupo e o grupo atual ao Close grupo e excluir a definição do Open grupo.
[^<>]* Corresponder a zero ou mais ocorrências de qualquer caractere que não seja um colchete angular esquerdo nem direito.
((?'Close-Open'>)[^<>]*)+ Corresponder uma ou mais ocorrências de um colchete angular reto, seguido por zero ou mais ocorrências de qualquer caractere que não seja um colchete angular esquerdo nem direito. Ao corresponder ao colchete angular direito, atribua a substring entre o grupo e o Open grupo atual ao Close grupo e exclua a Open definição do grupo. Este é o terceiro grupo de captura.
(((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)* Corresponder zero ou mais ocorrências do seguinte padrão: uma ou mais ocorrências de um colchete angular esquerdo, seguido por zero ou mais caracteres sem colchete angular, seguido por uma ou mais ocorrências de um colchete angular reto, seguido por zero ou mais ocorrências de colchetes não angulares. Ao corresponder ao colchete angular direito, exclua a Open definição do grupo e atribua a substring entre o Open grupo e o grupo atual ao Close grupo. Este é o primeiro grupo de captura.
(?(Open)(?!)) Se o Open grupo existir, abandone a correspondência se uma cadeia de caracteres vazia puder ser correspondida, mas não avance a posição do mecanismo de expressão regular na cadeia de caracteres. Esta é uma afirmação negativa de largura zero. Como uma cadeia de caracteres vazia está sempre implicitamente presente em uma cadeia de entrada, essa correspondência sempre falha. A falha desta correspondência indica que os colchetes angulares não estão equilibrados.
$ Corresponder ao final da cadeia de caracteres de entrada.

A subexpressão final, (?(Open)(?!)), indica se as construções de aninhamento na cadeia de caracteres de entrada estão devidamente equilibradas (por exemplo, se cada colchete angular esquerdo é correspondido por um colchete angular reto). Ele usa correspondência condicional com base em um grupo capturado válido; para obter mais informações, consulte Construções de alternância. Se o Open grupo for definido, o mecanismo de expressão regular tentará corresponder à subexpressão (?!) na cadeia de caracteres de entrada. O Open grupo deve ser definido somente se as construções de aninhamento estiverem desequilibradas. Portanto, o padrão a ser correspondido na cadeia de caracteres de entrada deve ser aquele que sempre faz com que a correspondência falhe. Nesse caso, (?!) é uma asserção lookahead negativa de largura zero que sempre falha, porque uma cadeia de caracteres vazia está sempre implicitamente presente na próxima posição na cadeia de entrada.

No exemplo, o mecanismo de expressão regular avalia a cadeia de caracteres de entrada "<abc><mno<xyz>>", conforme mostrado na tabela a seguir.

Passo Padrão Resultado
1 ^ Inicia a correspondência no início da cadeia de caracteres de entrada
2 [^<>]* Procura caracteres sem colchetes angulares antes do colchete angular esquerdo; não encontra correspondências.
3 (((?'Open'<) Corresponde ao colchete angular esquerdo em "<abc>" e atribui-o Open ao grupo.
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, portanto, o mecanismo de expressão regular não volta para o (?'Open'<)[^<>]*) subpadrão.
6 ((?'Close-Open'>) Corresponde ao colchete angular direito em "<abc>", atribui "abc", que é a substring entre o Open grupo e o colchete angular reto, ao Close grupo e exclui o valor atual ("<") do grupo, deixando-o Open vazio.
7 [^<>]* Procura caracteres sem colchetes angulares após o colchete angular reto; 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 reto, portanto, o mecanismo de expressão regular não volta para o ((?'Close-Open'>)[^<>]*) subpadrão.
9 )* O valor do primeiro grupo capturado é "<abc>".

O próximo caractere na cadeia de caracteres de entrada é um colchete angular esquerdo, de modo que o mecanismo de expressão regular volta ao (((?'Open'<) subpadrão.
10 (((?'Open'<) Corresponde ao colchete angular esquerdo em "<mno" e atribui-o Open ao grupo. A sua Group.Captures coleção tem agora um valor único, "<".
11 [^<>]* Corresponde a "mno".
12 )+ "<mno" é o valor do segundo grupo capturado.

O próximo caractere na cadeia de caracteres de entrada é um colchete angular esquerdo, de modo que o mecanismo de expressão regular volta ao (?'Open'<)[^<>]*) subpadrão.
13 (((?'Open'<) Corresponde ao colchete angular esquerdo em "<xyz>" e o atribui ao Open grupo. A Group.Captures coleção do Open grupo agora inclui duas capturas: o colchete angular esquerdo de "<mno", e o colchete angular esquerdo 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 é um colchete angular esquerdo, portanto, o mecanismo de expressão regular não volta para o (?'Open'<)[^<>]*) subpadrão.
16 ((?'Close-Open'>) Corresponde ao colchete angular direito em "<xyz>". "xyz", atribui a substring entre o Open grupo e o colchete angular direito ao Close grupo e exclui o valor atual do Open grupo. O valor da captura anterior (o colchete angular esquerdo em "<mno") torna-se o valor atual do Open grupo. A Captures coleção do Open grupo agora inclui uma única captura, o colchete angular esquerdo de "<xyz>".
17 [^<>]* Procura caracteres sem colchetes angulares; 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 reto, de modo que o mecanismo de expressão regular volta ao ((?'Close-Open'>)[^<>]*) subpadrão.
19 ((?'Close-Open'>) Corresponde ao colchete angular reto final em "xyz>>", atribui "mno<xyz>" (a substring entre o Open grupo e o colchete angular reto) ao Close grupo e exclui o valor atual do Open grupo. O Open grupo está agora vazio.
20 [^<>]* Procura caracteres sem colchetes angulares; 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 colchete angular reto, portanto, o mecanismo de expressão regular não volta para o ((?'Close-Open'>)[^<>]*) subpadrão.
22 )* O valor do primeiro grupo capturado é "<mno<xyz>>".

O próximo caractere na cadeia de caracteres de entrada não é um colchete angular esquerdo, portanto, o mecanismo de expressão regular não volta para o (((?'Open'<) subpadrão.
23 (?(Open)(?!)) O Open grupo não está definido, por isso nenhuma correspondência é tentada.
24 $ Corresponde ao final da cadeia de caracteres de entrada.

Grupos não capturados

A construção de agrupamento a seguir não captura a substring que é correspondida por uma subexpressão:

(?:subexpression)

Aqui, subexpressão é qualquer padrão de expressão regular válido. A construção de grupo sem captura é normalmente usada quando um quantificador é aplicado a um grupo, mas as substrings capturadas pelo grupo não são de interesse.

Nota

Se uma expressão regular incluir construções de agrupamento aninhadas, uma construção de grupo externa não capturadora não se aplicará às construções de grupo aninhado interno.

O exemplo a seguir ilustra uma expressão regular que inclui grupos que não capturam. Observe que a saída não inclui nenhum grupo capturado.

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: {0}", match.Value);
      for (int ctr = 1; ctr < match.Groups.Count; ctr++)
         Console.WriteLine("   Group {0}: {1}", 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 (?:\b(?:\w+)\W*)+\. regular corresponde a uma frase que é encerrada por um ponto. Como a expressão regular se concentra em frases e não em palavras individuais, construções de agrupamento são usadas exclusivamente como quantificadores. O padrão de expressão regular é interpretado como mostrado na tabela a seguir.

Padrão Description
\b Comece a partida com um limite de palavras.
(?:\w+) Corresponder a um ou mais caracteres de palavra. Não atribua o texto correspondente a um grupo capturado.
\W* Corresponder a zero ou mais caracteres que não sejam palavras.
(?:\b(?:\w+)\W*)+ Corresponder ao padrão de um ou mais caracteres de palavra começando em um limite de palavras, seguido por zero ou mais caracteres não verbais, uma ou mais vezes. Não atribua o texto correspondente a um grupo capturado.
\. Corresponda a um ponto.

Opções de grupo

A construção 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 minúsculas e desativa o modo de linha única. Para obter mais informações sobre as opções embutidas que você pode especificar, consulte Opções de expressão regular.

Nota

Você pode especificar opções que se aplicam a uma expressão regular inteira em vez de uma subexpressão usando um System.Text.RegularExpressions.Regex construtor de classe ou um método estático. Você também pode especificar opções embutidas que se aplicam após um ponto específico em uma expressão regular usando a (?imnsx-imnsx) construção de linguagem.

A construção de opções de grupo não é um grupo de captura. Ou seja, embora qualquer parte de uma cadeia de caracteres capturada pela subexpressão seja incluída na correspondência, ela não é incluída em um grupo capturado nem usada para preencher o GroupCollection objeto.

Por exemplo, a expressão \b(?ix: d \w+)\s regular no exemplo a seguir usa opções embutidas em uma construção de agrupamento para habilitar a correspondência sem diferenciação de maiúsculas e minúsculas e ignorar o espaço em branco do padrão na identificação de todas as palavras que começam com a letra "d". A expressão regular é definida conforme mostrado na tabela a seguir.

Padrão Description
\b Comece a partida com um limite de palavras.
(?ix: d \w+) Usando a correspondência que não diferencia maiúsculas de minúsculas e ignorando o espaço em branco nesse padrão, corresponda a um "d" seguido por um ou mais caracteres de palavra.
\s Corresponder 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("'{0}// found at index {1}.", match.Value, 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 de antecipação positivas de largura zero

A construção de agrupamento a seguir define uma asserção de lookahead positiva de largura zero:

(?=Subexpressão)

Aqui, subexpressão é qualquer padrão de expressão regular. Para que uma correspondência seja bem-sucedida, a cadeia de caracteres de entrada deve corresponder ao padrão de expressão regular na subexpressão, embora a substring correspondente não esteja incluída no resultado da correspondência. Uma afirmação de antecipação positiva de largura zero não retrocede.

Normalmente, uma asserção lookahead positiva de largura zero é encontrada no final de um padrão de expressão regular. Ele define uma substring que deve ser encontrada no final de uma string para que uma correspondência ocorra, mas que não deve ser incluída na correspondência. Também é útil para evitar retrocessos excessivos. Você pode usar uma asserção lookahead positiva de largura zero para garantir que um determinado grupo capturado comece com texto que corresponda a um subconjunto do padrão definido para esse grupo capturado. Por exemplo, se um grupo de captura corresponder a caracteres de palavras consecutivos, você poderá usar uma asserção de avanço positivo de largura zero para exigir que o primeiro caractere seja um caractere alfabético maiúsculo.

O exemplo a seguir usa uma asserção lookahead positiva de largura zero para corresponder à 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("'{0}' precedes 'is'.", match.Value);
         else
            Console.WriteLine("'{0}' does not match the pattern.", input);
      }
   }
}
// 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 \b\w+(?=\sis\b) regular é interpretada como mostrado na tabela a seguir.

Padrão Description
\b Comece a partida com um limite de palavras.
\w+ Corresponder a um ou mais caracteres de palavra.
(?=\sis\b) Determine se os caracteres de palavra são seguidos por um caractere de espaço em branco e a cadeia de caracteres "é", que termina em um limite de palavra. Em caso afirmativo, a correspondência é bem-sucedida.

Asserções prospetivas negativas de largura zero

A construção de agrupamento a seguir define uma asserção de lookahead 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 cadeia de caracteres de entrada não deve corresponder ao padrão de expressão regular na subexpressão, embora a cadeia de caracteres correspondente não esteja incluída no resultado da correspondência.

Uma asserção lookahead negativa de largura zero é normalmente usada no início ou no final de uma expressão regular. No início de uma expressão regular, ele pode 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. Neste caso, é frequentemente usado para limitar o retrocesso. No final de uma expressão regular, ele pode definir uma subexpressão que não pode ocorrer no final de uma correspondência.

O exemplo a seguir define uma expressão regular que usa uma asserçã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 \b(?!un)\w+\b regular é interpretada como mostrado na tabela a seguir.

Padrão Description
\b Comece a partida com um limite de palavras.
(?!un) Determine se os dois caracteres seguintes são "un". Se não estiverem, é possível uma correspondência.
\w+ Corresponder a um ou mais caracteres de palavra.
\b Termine a partida com um limite de palavras.

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 corresponder a 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 \b\w+\b(?!\p{P}) regular é interpretada como mostrado na tabela a seguir.

Padrão Description
\b Comece a partida com um limite de palavras.
\w+ Corresponder a um ou mais caracteres de palavra.
\b Termine a partida com um limite de palavras.
\p{P}) Se o caractere seguinte não for um símbolo de pontuação (como um ponto ou uma vírgula), a correspondência será bem-sucedida.

Asserções positivas de largura zero

A construção de agrupamento a seguir define uma asserção de lookbehind positiva de largura zero:

(?<=Subexpressão)

Aqui, subexpressão é qualquer padrão de expressão regular. Para que uma correspondência seja bem-sucedida, a subexpressão deve ocorrer na cadeia de caracteres de entrada à esquerda da posição atual, embora subexpression não esteja incluída no resultado da correspondência. Uma afirmação de olhar para trás positiva de largura zero não retrocede.

Asserções de lookbehind positivas de largura zero são normalmente usadas no início de expressões regulares. O padrão que eles definem é uma pré-condição para uma partida, embora não faça parte do resultado da partida.

Por exemplo, o exemplo a seguir corresponde aos dois últimos dígitos do ano para o século XXI (ou seja, requer que os dígitos "20" precedem a cadeia 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 (?<=\b20)\d{2}\b de expressão regular é interpretado como mostrado na tabela a seguir.

Padrão Description
\d{2} Corresponder a dois dígitos decimais.
(?<=\b20) Continue a correspondência se os dois dígitos decimais forem precedidos pelos dígitos decimais "20" em um limite de palavras.
\b Termine a partida com um limite de palavras.

Asserções de lookbehind positivas de largura zero também são usadas para limitar o retrocesso quando o último caractere ou caracteres em um grupo capturado devem ser um subconjunto dos caracteres que correspondem ao padrão de expressão regular desse grupo. Por exemplo, se um grupo capturar todos os caracteres de palavras consecutivos, você poderá usar uma asserção de lookbehind positivo de largura zero para exigir que o último caractere seja alfabético.

Asserções negativas de largura zero

A construção de agrupamento a seguir define uma asserção de lookbehind negativo de largura zero:

(?<!Subexpressão)

Aqui, subexpressão é qualquer padrão de expressão regular. Para que uma 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, qualquer substring que não corresponda subexpression não é incluída no resultado da correspondência.

Asserções negativas de largura zero são normalmente usadas no início de expressões regulares. O padrão que eles definem impede uma correspondência na cadeia de caracteres a seguir. Eles também são usados para limitar o retrocesso quando o último caractere ou caracteres em um grupo capturado não devem ser um ou mais dos caracteres que correspondem ao padrão de expressão regular desse grupo. Por exemplo, se um grupo capturar todos os caracteres de palavras consecutivas, você poderá usar uma asserção de lookbehind positivo de largura zero para exigir que o último caractere não seja um sublinhado (_).

O exemplo a seguir corresponde à data de qualquer dia da semana que não seja um fim de semana (ou seja, que não seja 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 (?<!(Saturday|Sunday) )\b\w+ \d{1,2}, \d{4}\b de expressão regular é interpretado como mostrado na tabela a seguir.

Padrão Description
\b Comece a partida com um limite de palavras.
\w+ Corresponder a um ou mais caracteres de palavra seguidos por um caractere de espaço em branco.
\d{1,2}, Corresponder a um ou dois dígitos decimais seguidos por um caractere de espaço em branco e uma vírgula.
\d{4}\b Corresponder a quatro dígitos decimais e terminar a correspondência em um limite de palavras.
(?<!(Saturday|Sunday) ) Se a partida for precedida por algo diferente das cordas "sábado" ou "domingo" seguidas de um espaço, a partida será bem-sucedida.

Grupos atómicos

A construção de agrupamento a seguir representa um grupo atômico (conhecido em alguns outros mecanismos de expressão regular como uma subexpressão sem retrocesso, uma subexpressão atômica ou uma subexpressão única):

(?>Subexpressão)

Aqui, subexpressão é qualquer padrão de expressão regular.

Normalmente, se uma expressão regular incluir um padrão de correspondência opcional ou alternativo e uma correspondência não for bem-sucedida, o mecanismo de expressão regular poderá se ramificar em várias direções para corresponder a uma cadeia de caracteres de entrada com um padrão. Se uma correspondência não for encontrada quando pegar a primeira ramificação, o mecanismo de expressão regular poderá fazer backup ou retroceder até o ponto em que fez a primeira partida e tentar a correspondência usando a segunda ramificação. Este processo pode continuar até que todos os ramos tenham sido tentados.

A (?>construção da linguagem de subexpressão) desativa o backtracking. O mecanismo de expressão regular corresponderá ao maior número possível de caracteres na cadeia de caracteres de entrada. Quando nenhuma outra correspondência for possível, ele não voltará atrás para tentar correspondências de padrões alternativos. (Ou seja, a subexpressão corresponde apenas às cadeias de caracteres que seriam correspondidas apenas pela subexpressão; ela não tenta corresponder a uma cadeia de caracteres com base na subexpressão e em quaisquer subexpressões que a seguem.)

Esta opção é recomendada se você souber que o backtracking não terá êxito. Impedir que o mecanismo de expressão regular execute pesquisas desnecessárias melhora o desempenho.

O exemplo a seguir ilustra como um grupo atômico modifica os resultados de uma correspondência de padrão. A expressão regular de backtracking corresponde com êxito a uma série de caracteres repetidos seguidos por mais uma ocorrência do mesmo caractere em um limite de palavra, mas a expressão regular nonbacktracking não.

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("{0}: ", 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 (?>(\w)\1+).\b regular nonbacktracking é definida conforme mostrado na tabela a seguir.

Padrão Description
(\w) Corresponda a um caractere de uma única palavra e atribua-o ao primeiro grupo de captura.
\1+ Corresponder ao valor da primeira substring capturada uma ou mais vezes.
. Combine com qualquer personagem.
\b Termine a partida com um limite de palavras.
(?>(\w)\1+) Corresponder a uma ou mais ocorrências de um caractere de palavra duplicado, mas não retroceder para corresponder ao último caractere em um limite de palavra.

Agrupando construções e objetos de expressão regular

As subcadeias de caracteres que são correspondidas por um grupo de captura de expressão regular são representadas por System.Text.RegularExpressions.Group objetos, que podem ser recuperados do System.Text.RegularExpressions.GroupCollection objeto retornado pela Match.Groups propriedade. O GroupCollection objeto é preenchido da seguinte forma:

  • O primeiro Group objeto da coleção (o objeto no índice zero) representa toda a correspondência.
  • O próximo conjunto de objetos representa grupos de Group captura sem nome (numerados). Eles aparecem na ordem em que são definidos na expressão regular, da esquerda para a direita. Os valores de índice desses grupos variam de 1 ao número de grupos de captura sem nome na coleção. (O índice de um determinado grupo é equivalente à sua retroreferência numerada. Para obter mais informações sobre backreferences, consulte Construções de backreference.)
  • O conjunto final de objetos representa grupos de Group 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 é maior do que o índice do último grupo de captura sem nome. Se não houver grupos de captura sem nome na expressão regular, o valor de índice do primeiro grupo de captura nomeado será um.

Se você aplicar um quantificador a um grupo de captura, as propriedades , Capture.ValueCapture.Indexe Capture.Length do objeto correspondente Group refletirão a última subcadeia de caracteres capturada por um grupo de captura. Você pode recuperar um conjunto completo de substrings capturadas por grupos que têm quantificadores do CaptureCollection objeto retornado pela Group.Captures propriedade.

O exemplo a seguir esclarece a relação entre os Group objetos 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: '{0}'", match.Value);
      for (int ctr = 1; ctr < match.Groups.Count; ctr++)
      {
         Console.WriteLine("   Group {0}: '{1}'", ctr, match.Groups[ctr].Value);
         int capCtr = 0;
         foreach (Capture capture in match.Groups[ctr].Captures)
         {
            Console.WriteLine("      Capture {0}: '{1}'", 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 (\b(\w+)\W+)+ de expressão regular extrai palavras individuais de uma cadeia de caracteres. É definido como mostrado na tabela a seguir.

Padrão Description
\b Comece a partida com um limite de palavras.
(\w+) Corresponder a um ou mais caracteres de palavra. Juntos, esses caracteres formam uma palavra. Este é o segundo grupo de captura.
\W+ Corresponder a um ou mais caracteres que não sejam palavras.
(\b(\w+)\W+) Corresponder ao padrão de um ou mais caracteres de palavra seguidos por um ou mais caracteres não verbais uma ou mais vezes. Este é o primeiro grupo de captura.

O segundo grupo de captura corresponde a cada palavra da frase. O primeiro grupo de captura corresponde a cada palavra, juntamente com a pontuação e o espaço em branco que se seguem à palavra. O Group objeto cujo índice é 2 fornece informações sobre o texto correspondente pelo segundo grupo de captura. O conjunto completo de palavras capturadas pelo grupo de captura está disponível a partir do CaptureCollection objeto retornado pela Group.Captures propriedade.

Consulte também