O modelo de objeto de expressão regular

Este tópico descreve o modelo do objeto usado ao trabalhar com expressões regulares do .NET. Ele contém as seções a seguir:

O mecanismo da expressão regular

O mecanismo de expressões regulares no .NET é representada pela classe Regex. O mecanismo de expressões regulares é responsável por analisar e compilar uma expressão regular e realizar operações que correspondem ao padrão da expressão regular com uma cadeia de caracteres de entrada. O mecanismo é o componente central no modelo do objeto da expressão regular do .NET.

Você pode usar o mecanismo de expressões regulares de duas maneiras:

  • Ao calcular os métodos estáticos da classe Regex. Os parâmetros do método incluem a cadeia de caracteres de entrada e o padrão da expressão regular. O mecanismo de expressões regulares armazena em cache expressões regulares que são usadas em chamadas de método estático; por isso, chamadas repetidas a métodos de expressão regular estáticos que usam a mesma expressão regular oferecem um desempenho relativamente bom.

  • Ao instanciar um objeto Regex, transmitindo uma expressão regular ao construtor da classe. Nesse caso, o objeto Regex é imutável (somente leitura) e representa um mecanismo de expressão regular que está ligado rigorosamente a uma única expressão regular. Como as expressões regulares usadas por instâncias Regex não são armazenadas em cache, você não deve instanciar um objeto Regex várias vezes com a mesma expressão regular.

Você pode chamar os métodos da classe Regex para realizar as seguintes operações:

  • Determinar se uma cadeia de caracteres corresponde a um padrão de expressão regular.

  • Extrair uma única correspondência ou a primeira correspondência.

  • Extrair todas as correspondências.

  • Substituir uma subcadeia de caracteres correspondida.

  • Dividir uma cadeia única em uma matriz de cadeias de caracteres.

Essas operações são descritas nas seções a seguir.

Correspondendo a um padrão de expressão regular

O método Regex.IsMatch retorna true se a cadeia corresponder ao padrão, ou false se não corresponder. Geralmente, o método IsMatch é usado para validar a entrada da cadeia de caracteres. Por exemplo, o código a seguir assegura que uma cadeia de caracteres corresponda a um número do cadastro de pessoas físicas válido nos Estados Unidos.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string[] values = { "111-22-3333", "111-2-3333"};
      string pattern = @"^\d{3}-\d{2}-\d{4}$";
      foreach (string value in values) {
         if (Regex.IsMatch(value, pattern))
            Console.WriteLine("{0} is a valid SSN.", value);
         else
            Console.WriteLine("{0}: Invalid", value);
      }
   }
}
// The example displays the following output:
//       111-22-3333 is a valid SSN.
//       111-2-3333: Invalid
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim values() As String = {"111-22-3333", "111-2-3333"}
        Dim pattern As String = "^\d{3}-\d{2}-\d{4}$"
        For Each value As String In values
            If Regex.IsMatch(value, pattern) Then
                Console.WriteLine("{0} is a valid SSN.", value)
            Else
                Console.WriteLine("{0}: Invalid", value)
            End If
        Next
    End Sub
End Module
' The example displays the following output:
'       111-22-3333 is a valid SSN.
'       111-2-3333: Invalid

O padrão da expressão regular ^\d{3}-\d{2}-\d{4}$ é interpretado conforme mostrado na tabela a seguir.

Padrão Descrição
^ Corresponder ao início da cadeia de caracteres de entrada.
\d{3} Corresponder a três dígitos decimais.
- Corresponder a um hífen.
\d{2} Corresponde a dois dígitos decimais.
- Corresponder a um hífen.
\d{4} Corresponder a quatro dígitos decimais.
$ Corresponder ao final da cadeia de caracteres de entrada.

Extraindo uma única correspondência ou a primeira correspondência

O método Regex.Match retorna um objeto Match que contém informações sobre a primeira subcadeia de caracteres que corresponde a um padrão de expressão regular. Se a propriedade Match.Success retornar true, indicando que uma correspondência foi localizada, você pode recuperar informações sobre correspondências subsequentes chamando o método Match.NextMatch. Essas chamadas de método podem continuar até que a propriedade Match.Success retorne false. Por exemplo, o código a seguir usa o método Regex.Match(String, String) para localizar a primeira ocorrência de uma palavra duplicada em uma cadeia de caracteres. Em seguida, ele chama o método Match.NextMatch para encontrar ocorrências adicionais. O exemplo examina a propriedade Match.Success após cada chamada de método para determinar se a correspondência atual foi bem-sucedida e se uma chamada para o método Match.NextMatch deve seguir.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string input = "This is a a farm that that raises dairy cattle.";
      string pattern = @"\b(\w+)\W+(\1)\b";
      Match match = Regex.Match(input, pattern);
      while (match.Success)
      {
         Console.WriteLine("Duplicate '{0}' found at position {1}.",
                           match.Groups[1].Value, match.Groups[2].Index);
         match = match.NextMatch();
      }
   }
}
// The example displays the following output:
//       Duplicate 'a' found at position 10.
//       Duplicate 'that' found at position 22.
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim input As String = "This is a a farm that that raises dairy cattle."
        Dim pattern As String = "\b(\w+)\W+(\1)\b"
        Dim match As Match = Regex.Match(input, pattern)
        Do While match.Success
            Console.WriteLine("Duplicate '{0}' found at position {1}.", _
                              match.Groups(1).Value, match.Groups(2).Index)
            match = match.NextMatch()
        Loop
    End Sub
End Module
' The example displays the following output:
'       Duplicate 'a' found at position 10.
'       Duplicate 'that' found at position 22.

O padrão da expressão regular \b(\w+)\W+(\1)\b é interpretado conforme mostrado na tabela a seguir.

Padrão Descrição
\b Começa a correspondência em um limite de palavra.
(\w+) Fazer a correspondência a um ou mais caracteres de palavra. Este é o primeiro grupo de captura.
\W+ Estabeleça a correspondência com um ou mais caracteres que não compõem palavras.
(\1) Corresponder à primeira cadeia capturada. Este é o segundo grupo de captura.
\b Termina a correspondência em um limite de palavra.

Extraindo todas as correspondências

O método Regex.Matches retorna um objeto MatchCollection que contém informações sobre todas as correspondências que o mecanismo de expressão regular localizou na cadeia de caracteres de entrada. Por exemplo, o exemplo anterior poderia ser regravado para chamar o método Matches ao invés dos métodos Match e NextMatch.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string input = "This is a a farm that that raises dairy cattle.";
      string pattern = @"\b(\w+)\W+(\1)\b";
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine("Duplicate '{0}' found at position {1}.",
                           match.Groups[1].Value, match.Groups[2].Index);
   }
}
// The example displays the following output:
//       Duplicate 'a' found at position 10.
//       Duplicate 'that' found at position 22.
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim input As String = "This is a a farm that that raises dairy cattle."
        Dim pattern As String = "\b(\w+)\W+(\1)\b"
        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine("Duplicate '{0}' found at position {1}.", _
                              match.Groups(1).Value, match.Groups(2).Index)
        Next
    End Sub
End Module
' The example displays the following output:
'       Duplicate 'a' found at position 10.
'       Duplicate 'that' found at position 22.

Substituindo uma subcadeia de caracteres correspondida

O método Regex.Replace substitui cada subcadeia de caracteres que corresponde ao padrão da expressão regular com uma cadeia de caracteres ou padrão de expressão regular especificado, e retorna a cadeia de caracteres de entrada inteira com as substituições. Por exemplo, o código a seguir adiciona um símbolo de moeda dos Estados Unidos antes de um número decimal em uma cadeia de caracteres.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b\d+\.\d{2}\b";
      string replacement = "$$$&";
      string input = "Total Cost: 103.64";
      Console.WriteLine(Regex.Replace(input, pattern, replacement));
   }
}
// The example displays the following output:
//       Total Cost: $103.64
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "\b\d+\.\d{2}\b"
        Dim replacement As String = "$$$&"
        Dim input As String = "Total Cost: 103.64"
        Console.WriteLine(Regex.Replace(input, pattern, replacement))
    End Sub
End Module
' The example displays the following output:
'       Total Cost: $103.64

O padrão da expressão regular \b\d+\.\d{2}\b é interpretado conforme mostrado na tabela a seguir.

Padrão Descrição
\b Começar a correspondência em um limite de palavra.
\d+ Corresponde a um ou mais dígitos decimais.
\. Corresponde a um ponto final.
\d{2} Corresponde a dois dígitos decimais.
\b Termina a correspondência em um limite de palavra.

O padrão de substituição $$$& é interpretado conforme a tabela a seguir.

Padrão Cadeia de caracteres de substituição
$$ O caractere de cifrão ($).
$& A subcadeia de caracteres correspondida inteira.

Dividindo uma cadeia de caracteres única em uma matriz de cadeias de caracteres

O método Regex.Split divide a cadeia de caracteres de entrada nas posições definidas por uma correspondência de expressão regular. Por exemplo, o código a seguir coloca os itens em uma lista numerada em uma matriz de cadeia de caracteres.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string input = "1. Eggs 2. Bread 3. Milk 4. Coffee 5. Tea";
      string pattern = @"\b\d{1,2}\.\s";
      foreach (string item in Regex.Split(input, pattern))
      {
         if (! String.IsNullOrEmpty(item))
            Console.WriteLine(item);
      }
   }
}
// The example displays the following output:
//       Eggs
//       Bread
//       Milk
//       Coffee
//       Tea
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim input As String = "1. Eggs 2. Bread 3. Milk 4. Coffee 5. Tea"
        Dim pattern As String = "\b\d{1,2}\.\s"
        For Each item As String In Regex.Split(input, pattern)
            If Not String.IsNullOrEmpty(item) Then
                Console.WriteLine(item)
            End If
        Next
    End Sub
End Module
' The example displays the following output:
'       Eggs
'       Bread
'       Milk
'       Coffee
'       Tea

O padrão da expressão regular \b\d{1,2}\.\s é interpretado conforme mostrado na tabela a seguir.

Padrão Descrição
\b Começar a correspondência em um limite de palavra.
\d{1,2} Corresponder a um ou dois dígitos decimais.
\. Corresponde a um ponto final.
\s Corresponde a um caractere de espaço em branco.

A coleção de correspondência e os objetos de correspondência

Métodos regex retornam dois objetos que fazem parte do modelos de objeto de expressão regular: os objetos MatchCollection e Match.

A coleção de correspondência

O método Regex.Matches retorna um objeto MatchCollection que contém objetos Match que representam todas as correspondências localizadas pelo mecanismo de expressão regular na ordem em que elas ocorrem na cadeia de caracteres de entrada. Se não houver correspondências, o método retorna um objeto MatchCollection sem membros. A propriedade MatchCollection.Item[] permite que você acesse membros individuais da coleção por índice, de zero a um valor uma vez menor do que o valor da propriedade MatchCollection.Count. Item[] é o indexador da coleção (no C#) e a propriedade padrão (no Visual Basic).

Por padrão, a chamada para o método Regex.Matches usa a avaliação lenta para preencher o objeto MatchCollection. O acesso a propriedades que requerem uma coleção completamente preenchida, como as propriedades MatchCollection.Count e MatchCollection.Item[], pode envolver uma penalização de desempenho. Como resultado, recomendamos que você acesse a coleção usando o objeto IEnumerator retornado pelo método MatchCollection.GetEnumerator. Linguagens individuais oferecem constructos, como For Each no Visual Basic e foreach no C#, que encapsulam a interface IEnumerator da coleção.

O exemplo a seguir usa o método Regex.Matches(String) para preencher um objeto MatchCollection com todas as correspondências localizadas em uma cadeia de caracteres de entrada. O exemplo enumera a coleção, copia as correspondências para uma matriz de cadeia de caracteres e registra as posições dos caracteres em uma matriz de inteiros.

using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
       MatchCollection matches;
       List<string> results = new List<string>();
       List<int> matchposition = new List<int>();

       // Create a new Regex object and define the regular expression.
       Regex r = new Regex("abc");
       // Use the Matches method to find all matches in the input string.
       matches = r.Matches("123abc4abcd");
       // Enumerate the collection to retrieve all matches and positions.
       foreach (Match match in matches)
       {
          // Add the match string to the string array.
           results.Add(match.Value);
           // Record the character position where the match was found.
           matchposition.Add(match.Index);
       }
       // List the results.
       for (int ctr = 0; ctr < results.Count; ctr++)
         Console.WriteLine("'{0}' found at position {1}.",
                           results[ctr], matchposition[ctr]);
   }
}
// The example displays the following output:
//       'abc' found at position 3.
//       'abc' found at position 7.
Imports System.Collections.Generic
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim matches As MatchCollection
        Dim results As New List(Of String)
        Dim matchposition As New List(Of Integer)

        ' Create a new Regex object and define the regular expression.
        Dim r As New Regex("abc")
        ' Use the Matches method to find all matches in the input string.
        matches = r.Matches("123abc4abcd")
        ' Enumerate the collection to retrieve all matches and positions.
        For Each match As Match In matches
            ' Add the match string to the string array.
            results.Add(match.Value)
            ' Record the character position where the match was found.
            matchposition.Add(match.Index)
        Next
        ' List the results.
        For ctr As Integer = 0 To results.Count - 1
            Console.WriteLine("'{0}' found at position {1}.", _
                              results(ctr), matchposition(ctr))
        Next
    End Sub
End Module
' The example displays the following output:
'       'abc' found at position 3.
'       'abc' found at position 7.

A correspondência

A classe Match representa o resultado de uma única correspondência de expressão regular. É possível acessar objetos Match de duas formas:

  • Recuperando-os do objeto MatchCollection que é retornado pelo método Regex.Matches. Para recuperar objetos Match individuais, itere a coleção usando um constructo foreach (no C#) ou For Each...Next (no Visual Basic) ou use a propriedade MatchCollection.Item[] para recuperar um objeto Match específico por índice ou por nome. Também é possível recuperar objetos Match individuais da coleção iterando a coleção por índice, de zero a um valor uma vez menor do que o número de objetos na coleção de dados. Entretanto, esse método não utiliza a avaliação lenta, pois ele acessa a propriedade MatchCollection.Count.

    O exemplo a seguir recupera objetos Match individuais de um objeto MatchCollection iterando a coleção usando o constructo foreach ou For Each...Next. A expressão regular simplesmente corresponde a cadeia de caracteres “abc” na cadeia de caracteres de entrada.

    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
       public static void Main()
       {
          string pattern = "abc";
          string input = "abc123abc456abc789";
          foreach (Match match in Regex.Matches(input, pattern))
             Console.WriteLine("{0} found at position {1}.",
                               match.Value, match.Index);
       }
    }
    // The example displays the following output:
    //       abc found at position 0.
    //       abc found at position 6.
    //       abc found at position 12.
    
    Imports System.Text.RegularExpressions
    
    Module Example
        Public Sub Main()
            Dim pattern As String = "abc"
            Dim input As String = "abc123abc456abc789"
            For Each match As Match In Regex.Matches(input, pattern)
                Console.WriteLine("{0} found at position {1}.", _
                                  match.Value, match.Index)
            Next
        End Sub
    End Module
    ' The example displays the following output:
    '       abc found at position 0.
    '       abc found at position 6.
    '       abc found at position 12.
    
  • Ao chamar o método Regex.Match, que retorna um objeto Match que representa a primeira correspondência em uma cadeia de caracteres ou parte de uma cadeia. É possível determinar se a correspondência foi localizada recuperando o valor da propriedade Match.Success. Para recuperar objetos Match que representam correspondências subsequentes, chame o método Match.NextMatch repetidamente, até que a propriedade Success do objeto Match retornado seja false.

    O exemplo a seguir usa os métodos Regex.Match(String, String) e Match.NextMatch para corresponder a cadeia de caracteres "abc" na cadeia de caracteres de entrada.

    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
       public static void Main()
       {
          string pattern = "abc";
          string input = "abc123abc456abc789";
          Match match = Regex.Match(input, pattern);
          while (match.Success)
          {
             Console.WriteLine("{0} found at position {1}.",
                               match.Value, match.Index);
             match = match.NextMatch();
          }
       }
    }
    // The example displays the following output:
    //       abc found at position 0.
    //       abc found at position 6.
    //       abc found at position 12.
    
    Imports System.Text.RegularExpressions
    
    Module Example
        Public Sub Main()
            Dim pattern As String = "abc"
            Dim input As String = "abc123abc456abc789"
            Dim match As Match = Regex.Match(input, pattern)
            Do While match.Success
                Console.WriteLine("{0} found at position {1}.", _
                                  match.Value, match.Index)
                match = match.NextMatch()
            Loop
        End Sub
    End Module
    ' The example displays the following output:
    '       abc found at position 0.
    '       abc found at position 6.
    '       abc found at position 12.
    

Duas propriedades da classe Match retornam objetos de coleção:

  • A propriedade Match.Groups retorna um objeto GroupCollection que contém informações sobre as subcadeias de caracteres que correspondem grupos de captura no padrão de expressão regular.

  • A propriedade Match.Captures retorna um objeto CaptureCollection de uso limitado. A coleção não é preenchida para um objeto Match cuja propriedade Success é false. Caso contrário, ela contém um único objeto Capture que possui as mesmas informações do objeto Match.

Para obter mais informações sobre esses objetos, consulte as seções A coleção de Grupo e A coleção Capture mais adiante neste tópico.

Duas propriedades adicionais da classe Match oferecem informações sobre a correspondência. A propriedade Match.Value retorna a subcadeia na cadeia de caracteres de entrada que corresponde ao padrão de expressão regular. A propriedade Match.Index retorna a posição inicial baseada em zero da cadeia correspondida na cadeia de caracteres de entrada.

A classe Match também tem dois métodos de correspondência de padrões:

  • O método Match.NextMatch localiza a correspondência após a correspondência representada pelo objeto Match atual e retorna um objeto Match que representa essa correspondência.

  • O método Match.Result realiza uma operação de substituição especificada na cadeia de caracteres correspondida e retorna o resultado.

O exemplo a seguir usa o método Match.Result para inserir um símbolo de $ e um espaço antes de cada número que inclua dois dígitos fracionais.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b\d+(,\d{3})*\.\d{2}\b";
      string input = "16.32\n194.03\n1,903,672.08";

      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine(match.Result("$$ $&"));
   }
}
// The example displays the following output:
//       $ 16.32
//       $ 194.03
//       $ 1,903,672.08
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "\b\d+(,\d{3})*\.\d{2}\b"
        Dim input As String = "16.32" + vbCrLf + "194.03" + vbCrLf + "1,903,672.08"

        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine(match.Result("$$ $&"))
        Next
    End Sub
End Module
' The example displays the following output:
'       $ 16.32
'       $ 194.03
'       $ 1,903,672.08

O padrão de expressão regular \b\d+(,\d{3})*\.\d{2}\b é definido conforme mostrado na tabela a seguir.

Padrão Descrição
\b Começar a correspondência em um limite de palavra.
\d+ Corresponde a um ou mais dígitos decimais.
(,\d{3})* Corresponder a zero ou mais ocorrências de uma vírgula seguida por três dígitos decimais.
\. Corresponder ao caractere de vírgula decimal.
\d{2} Corresponde a dois dígitos decimais.
\b Termina a correspondência em um limite de palavra.

O padrão de substituição $$ $& indica que a subcadeia de caracteres correspondida deve ser substituída por um símbolo de cifrão ($) (o padrão $$), um espaço e o valor da correspondência (o padrão $&).

Voltar ao início

A coleção de grupo

A propriedade Match.Groups retorna um objeto GroupCollection que contém Group objetos que representam grupos capturados em uma única correspondência. O primeiro objeto Group na coleção (no índice 0) representa a correspondência inteira. Cada objeto que se segue representa os resultados de um único grupo de captura.

É possível recuperar objetos Group individuais na coleção usando a propriedade GroupCollection.Item[]. É possível recuperar grupos não nomeados por sua posição ordinal na coleção e recuperar grupos nomeados por nome ou posição ordinal. Capturas não nomeadas aparecem primeiro na coleção e são indexadas da esquerda para a direita na ordem na qual aparecem no padrão de expressão regular. Capturas nomeadas são indexadas após as capturas não nomeadas, da esquerda para a direita, na ordem em que aparecem no padrão de expressão regular. Para determinar quais grupos numerados estão disponíveis na coleção retornada para um método específico de correspondência de expressão regular, você pode chamar o método da instância Regex.GetGroupNumbers. Para determinar quais grupos nomeados estão disponíveis na coleção, você pode chamar o método da instância Regex.GetGroupNames. Os dois métodos são especificamente úteis em rotinas gerais que analisam as correspondências encontradas por qualquer expressão regular.

A propriedade GroupCollection.Item[] é o indexador da coleção no C# e a propriedade padrão do objeto da coleção no Visual Basic. Isso significa que objetos Group individuais podem ser acessados por índice (ou por nome, no caso de grupos nomeados) como a seguir:

Group group = match.Groups[ctr];
Dim group As Group = match.Groups(ctr)

O exemplo a seguir define uma expressão regular que usa constructos de agrupamento para capturar o mês, o dia e o ano de uma data.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b(\w+)\s(\d{1,2}),\s(\d{4})\b";
      string input = "Born: July 28, 1989";
      Match match = Regex.Match(input, pattern);
      if (match.Success)
         for (int ctr = 0; ctr <  match.Groups.Count; ctr++)
            Console.WriteLine("Group {0}: {1}", ctr, match.Groups[ctr].Value);
    }
}
// The example displays the following output:
//       Group 0: July 28, 1989
//       Group 1: July
//       Group 2: 28
//       Group 3: 1989
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "\b(\w+)\s(\d{1,2}),\s(\d{4})\b"
        Dim input As String = "Born: July 28, 1989"
        Dim match As Match = Regex.Match(input, pattern)
        If match.Success Then
            For ctr As Integer = 0 To match.Groups.Count - 1
                Console.WriteLine("Group {0}: {1}", ctr, match.Groups(ctr).Value)
            Next
        End If
    End Sub
End Module
' The example displays the following output:
'       Group 0: July 28, 1989
'       Group 1: July
'       Group 2: 28
'       Group 3: 1989

O padrão de expressão regular \b(\w+)\s(\d{1,2}),\s(\d{4})\b é definido conforme mostrado na tabela a seguir.

Padrão Descrição
\b Começar a correspondência em um limite de palavra.
(\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.
(\d{1,2}) Corresponder a um ou dois dígitos decimais. Este é o segundo grupo de captura.
, Corresponde a uma vírgula.
\s Corresponde a um caractere de espaço em branco.
(\d{4}) Corresponder a quatro dígitos decimais. Este é o terceiro grupo de captura.
\b Termina a correspondência em um limite de palavra.

Voltar ao início

O grupo capturado

A classe Group representa o resultado de um único grupo de captura. Objetos de grupo que representam os grupos de captura definidos em uma expressão regular são retornados pela propriedade Item[] do objeto GroupCollection retornado pela propriedade Match.Groups. A propriedade Item[] é o indexador (no C#) e a propriedade padrão (no Visual Basic) da classe Group. Você também pode recuperar membros individuais iterando a coleção usando o constructo foreach ou For Each. Para ver um exemplo, consulte a seção anterior.

O exemplo a seguir usa constructos de agrupamento aninhados para capturar subcadeias de caracteres em grupos. O padrão de expressão regular (a(b))c corresponde à cadeia de caracteres “abc”. Ele atribui a subcadeia “ab” ao primeiro grupo de captura e a subcadeia de caracteres “b” ao segundo grupo de captura.

var matchposition = new List<int>();
var results = new List<string>();
// Define substrings abc, ab, b.
var r = new Regex("(a(b))c");
Match m = r.Match("abdabc");
for (int i = 0; m.Groups[i].Value != ""; i++)
{
    // Add groups to string array.
    results.Add(m.Groups[i].Value);
    // Record character position.
    matchposition.Add(m.Groups[i].Index);
}

// Display the capture groups.
for (int ctr = 0; ctr < results.Count; ctr++)
    Console.WriteLine("{0} at position {1}",
                      results[ctr], matchposition[ctr]);
// The example displays the following output:
//       abc at position 3
//       ab at position 3
//       b at position 4
Dim matchposition As New List(Of Integer)
Dim results As New List(Of String)
' Define substrings abc, ab, b.
Dim r As New Regex("(a(b))c")
Dim m As Match = r.Match("abdabc")
Dim i As Integer = 0
While Not (m.Groups(i).Value = "")
    ' Add groups to string array.
    results.Add(m.Groups(i).Value)
    ' Record character position. 
    matchposition.Add(m.Groups(i).Index)
    i += 1
End While

' Display the capture groups.
For ctr As Integer = 0 to results.Count - 1
    Console.WriteLine("{0} at position {1}", _
                      results(ctr), matchposition(ctr))
Next
' The example displays the following output:
'       abc at position 3
'       ab at position 3
'       b at position 4

O exemplo a seguir usa constructos de agrupamento nomeados para capturar subcadeias de caracteres de uma cadeia que contém dados no formato “DATANAME:VALUE”, que a expressão regular divide usando dois pontos (:).

var r = new Regex(@"^(?<name>\w+):(?<value>\w+)");
Match m = r.Match("Section1:119900");
Console.WriteLine(m.Groups["name"].Value);
Console.WriteLine(m.Groups["value"].Value);
// The example displays the following output:
//       Section1
//       119900
Dim r As New Regex("^(?<name>\w+):(?<value>\w+)")
Dim m As Match = r.Match("Section1:119900")
Console.WriteLine(m.Groups("name").Value)
Console.WriteLine(m.Groups("value").Value)
' The example displays the following output:
'       Section1
'       119900

O padrão de expressão regular ^(?<name>\w+):(?<value>\w+) é definido conforme mostrado na tabela a seguir.

Padrão Descrição
^ Começar a correspondência no início da cadeia de caracteres de entrada.
(?<name>\w+) Fazer a correspondência a um ou mais caracteres de palavra. O nome deste grupo de captura é name.
: Corresponder a dois pontos.
(?<value>\w+) Fazer a correspondência a um ou mais caracteres de palavra. O nome deste grupo de captura é value.

As propriedades da classe Group fornecem informações sobre o grupo capturado: a propriedade Group.Value contém a subcadeia de caracteres capturada, a propriedade Group.Index indica a posição inicial do grupo capturado no texto de entrada, a propriedade Group.Length contém o comprimento do texto capturado e a propriedade Group.Success indica se uma subcadeia de caracteres corresponde ao padrão definido pelo grupo de captura.

Aplicar quantificadores a um grupo (para obter mais informações, confira Quantificadores) modifica a relação de uma captura por grupo de captura de duas formas:

  • Se o quantificador * ou *? (que especifica zero ou mais correspondências) for aplicado a um grupo, um grupo de captura pode não ter uma correspondência na cadeia de caracteres de entrada. Quando não há texto capturado, as propriedades do objeto Group são definidas como mostrado na tabela a seguir.

    Propriedade do grupo Valor
    Success false
    Value String.Empty
    Length 0

    O exemplo a seguir ilustra esse cenário. No padrão de expressão regular aaa(bbb)*ccc, o primeiro grupo de captura (a subcadeia de caracteres “bbb”) pode ser correspondido a zero ou mais vezes. Como a cadeia de caracteres de entrada “aaaccc” corresponde ao padrão, o grupo de captura não tem correspondência.

    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
       public static void Main()
       {
          string pattern = "aaa(bbb)*ccc";
          string input = "aaaccc";
          Match match = Regex.Match(input, pattern);
          Console.WriteLine("Match value: {0}", match.Value);
          if (match.Groups[1].Success)
             Console.WriteLine("Group 1 value: {0}", match.Groups[1].Value);
          else
             Console.WriteLine("The first capturing group has no match.");
       }
    }
    // The example displays the following output:
    //       Match value: aaaccc
    //       The first capturing group has no match.
    
    Imports System.Text.RegularExpressions
    
    Module Example
        Public Sub Main()
            Dim pattern As String = "aaa(bbb)*ccc"
            Dim input As String = "aaaccc"
            Dim match As Match = Regex.Match(input, pattern)
            Console.WriteLine("Match value: {0}", match.Value)
            If match.Groups(1).Success Then
                Console.WriteLine("Group 1 value: {0}", match.Groups(1).Value)
            Else
                Console.WriteLine("The first capturing group has no match.")
            End If
        End Sub
    End Module
    ' The example displays the following output:
    '       Match value: aaaccc
    '       The first capturing group has no match.
    
  • Os quantificadores podem corresponder a diversas ocorrências de um padrão que é definido por um grupo de captura. Nesse caso, as propriedades Value e Length de um objeto Group contêm informações somente sobre a última subcadeia de caracteres capturada. Por exemplo, a seguinte expressão regular corresponde a uma única sentença que termina com um ponto. Ela utiliza dois constructos de agrupamento: o primeiro captura palavras individuais, juntamente com um caractere de espaço em branco; o segundo captura palavras individuais. Como a saída do exemplo mostra, embora a expressão regular tenha sucesso ao capturar uma sequência inteira, o segundo grupo de captura só captura a última palavra.

    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
       public static void Main()
       {
          string pattern = @"\b((\w+)\s?)+\.";
          string input = "This is a sentence. This is another sentence.";
          Match match = Regex.Match(input, pattern);
          if (match.Success)
          {
             Console.WriteLine("Match: " + match.Value);
             Console.WriteLine("Group 2: " + match.Groups[2].Value);
          }
       }
    }
    // The example displays the following output:
    //       Match: This is a sentence.
    //       Group 2: sentence
    
    Imports System.Text.RegularExpressions
    
    Module Example
        Public Sub Main()
            Dim pattern As String = "\b((\w+)\s?)+\."
            Dim input As String = "This is a sentence. This is another sentence."
            Dim match As Match = Regex.Match(input, pattern)
            If match.Success Then
                Console.WriteLine("Match: " + match.Value)
                Console.WriteLine("Group 2: " + match.Groups(2).Value)
            End If
        End Sub
    End Module
    ' The example displays the following output:
    '       Match: This is a sentence.
    '       Group 2: sentence
    

Voltar ao início

A coleção de captura

O objeto Group contém informações somente sobre a última captura. No entanto, o conjunto inteiro de capturas realizadas por um grupo de captura ainda estará disponível do objeto CaptureCollection que é retornado pela propriedade Group.Captures. Cada membro da coleção é um objeto Capture que representa uma captura realizada por esse grupo de captura, na ordem na qual elas foram capturadas (e, portanto, na ordem em que as cadeias capturadas foram correspondidas da esquerda para a direita na cadeia de caracteres de entrada). Você pode recuperar objetos Capture individuais na coleção de duas formas:

  • Ao iterar pela coleção usando um constructo como foreach (no C#) ou For Each (no Visual Basic).

  • Ao usar a propriedade CaptureCollection.Item[] para recuperar um objeto específico por índice. A propriedade Item[] é a propriedade padrão (no Visual Basic) ou o indexador (no C#) do objeto CaptureCollection.

Se um quantificador não for aplicado a um grupo de captura, o objeto CaptureCollection conterá um único objeto Capture de pouco interesse, pois ele fornece informações sobre a mesma correspondência que seu objeto Group. Se um quantificador for aplicado a um grupo de captura, o objeto CaptureCollection conterá todas as capturas realizadas pelo grupo de captura, e o último membro da coleção representará a mesma captura do objeto Group.

Por exemplo, se você usar o padrão de expressão regular ((a(b))c)+ (em que o quantificador + especifica uma ou mais correspondências) para capturar correspondências da cadeia de caracteres "abcabcabc", o objeto CaptureCollection para cada objeto Group conterá três membros.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = "((a(b))c)+";
      string input = "abcabcabc";

      Match match = Regex.Match(input, pattern);
      if (match.Success)
      {
         Console.WriteLine("Match: '{0}' at position {1}",
                           match.Value, match.Index);
         GroupCollection groups = match.Groups;
         for (int ctr = 0; ctr < groups.Count; ctr++) {
            Console.WriteLine("   Group {0}: '{1}' at position {2}",
                              ctr, groups[ctr].Value, groups[ctr].Index);
            CaptureCollection captures = groups[ctr].Captures;
            for (int ctr2 = 0; ctr2 < captures.Count; ctr2++) {
               Console.WriteLine("      Capture {0}: '{1}' at position {2}",
                                 ctr2, captures[ctr2].Value, captures[ctr2].Index);
            }
         }
      }
   }
}
// The example displays the following output:
//       Match: 'abcabcabc' at position 0
//          Group 0: 'abcabcabc' at position 0
//             Capture 0: 'abcabcabc' at position 0
//          Group 1: 'abc' at position 6
//             Capture 0: 'abc' at position 0
//             Capture 1: 'abc' at position 3
//             Capture 2: 'abc' at position 6
//          Group 2: 'ab' at position 6
//             Capture 0: 'ab' at position 0
//             Capture 1: 'ab' at position 3
//             Capture 2: 'ab' at position 6
//          Group 3: 'b' at position 7
//             Capture 0: 'b' at position 1
//             Capture 1: 'b' at position 4
//             Capture 2: 'b' at position 7
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "((a(b))c)+"
        Dim input As STring = "abcabcabc"

        Dim match As Match = Regex.Match(input, pattern)
        If match.Success Then
            Console.WriteLine("Match: '{0}' at position {1}", _
                              match.Value, match.Index)
            Dim groups As GroupCollection = match.Groups
            For ctr As Integer = 0 To groups.Count - 1
                Console.WriteLine("   Group {0}: '{1}' at position {2}", _
                                  ctr, groups(ctr).Value, groups(ctr).Index)
                Dim captures As CaptureCollection = groups(ctr).Captures
                For ctr2 As Integer = 0 To captures.Count - 1
                    Console.WriteLine("      Capture {0}: '{1}' at position {2}", _
                                      ctr2, captures(ctr2).Value, captures(ctr2).Index)
                Next
            Next
        End If
    End Sub
End Module
' The example displays the following output:
'       Match: 'abcabcabc' at position 0
'          Group 0: 'abcabcabc' at position 0
'             Capture 0: 'abcabcabc' at position 0
'          Group 1: 'abc' at position 6
'             Capture 0: 'abc' at position 0
'             Capture 1: 'abc' at position 3
'             Capture 2: 'abc' at position 6
'          Group 2: 'ab' at position 6
'             Capture 0: 'ab' at position 0
'             Capture 1: 'ab' at position 3
'             Capture 2: 'ab' at position 6
'          Group 3: 'b' at position 7
'             Capture 0: 'b' at position 1
'             Capture 1: 'b' at position 4
'             Capture 2: 'b' at position 7

O exemplo a seguir usa a expressão regular (Abc)+ para localizar uma ou mais execuções consecutivas da cadeia de caracteres “Abc” na cadeia “XYZAbcAbcAbcXYZAbcAb”. O exemplo ilustra o uso da propriedade Group.Captures para retornar vários grupos de subcadeias de caracteres capturadas.

int counter;
Match m;
CaptureCollection cc;
GroupCollection gc;

// Look for groupings of "Abc".
var r = new Regex("(Abc)+");
// Define the string to search.
m = r.Match("XYZAbcAbcAbcXYZAbcAb");
gc = m.Groups;

// Display the number of groups.
Console.WriteLine("Captured groups = " + gc.Count.ToString());

// Loop through each group.
for (int i = 0; i < gc.Count; i++)
{
    cc = gc[i].Captures;
    counter = cc.Count;

    // Display the number of captures in this group.
    Console.WriteLine("Captures count = " + counter.ToString());

    // Loop through each capture in the group.
    for (int ii = 0; ii < counter; ii++)
    {
        // Display the capture and its position.
        Console.WriteLine(cc[ii] + "   Starts at character " +
             cc[ii].Index);
    }
}
// The example displays the following output:
//       Captured groups = 2
//       Captures count = 1
//       AbcAbcAbc   Starts at character 3
//       Captures count = 3
//       Abc   Starts at character 3
//       Abc   Starts at character 6
//       Abc   Starts at character 9
Dim counter As Integer
Dim m As Match
Dim cc As CaptureCollection
Dim gc As GroupCollection

' Look for groupings of "Abc".
Dim r As New Regex("(Abc)+")
' Define the string to search.
m = r.Match("XYZAbcAbcAbcXYZAbcAb")
gc = m.Groups

' Display the number of groups.
Console.WriteLine("Captured groups = " & gc.Count.ToString())

' Loop through each group.
Dim i, ii As Integer
For i = 0 To gc.Count - 1
    cc = gc(i).Captures
    counter = cc.Count

    ' Display the number of captures in this group.
    Console.WriteLine("Captures count = " & counter.ToString())

    ' Loop through each capture in the group.            
    For ii = 0 To counter - 1
        ' Display the capture and its position.
        Console.WriteLine(cc(ii).ToString() _
            & "   Starts at character " & cc(ii).Index.ToString())
    Next ii
Next i
' The example displays the following output:
'       Captured groups = 2
'       Captures count = 1
'       AbcAbcAbc   Starts at character 3
'       Captures count = 3
'       Abc   Starts at character 3
'       Abc   Starts at character 6
'       Abc   Starts at character 9  

Voltar ao início

A captura individual

A classe Capture contém os resultados de uma única captura de subexpressão. A propriedade Capture.Value contém o texto correspondido, e a propriedade Capture.Index indica a posição baseada em zero na cadeia de caracteres de entrada na qual a subcadeia de caracteres correspondida começa.

O exemplo a seguir analisa uma cadeia de caracteres de entrada para a temperatura das cidades escolhidas. Uma vírgula (“,”) é usada para separar uma cidade e sua temperatura, enquanto um ponto e vírgula (“;”) é usado para separar os dados de cada cidade. A cadeia de caracteres de entrada inteira representa uma única correspondência. No padrão de expressão regular ((\w+(\s\w+)*),(\d+);)+, usado para analisar a cadeia de caracteres, o nome da cidade é atribuído ao segundo grupo de captura, enquanto a temperatura é atribuída ao quarto grupo de captura.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string input = "Miami,78;Chicago,62;New York,67;San Francisco,59;Seattle,58;";
      string pattern = @"((\w+(\s\w+)*),(\d+);)+";
      Match match = Regex.Match(input, pattern);
      if (match.Success)
      {
         Console.WriteLine("Current temperatures:");
         for (int ctr = 0; ctr < match.Groups[2].Captures.Count; ctr++)
            Console.WriteLine("{0,-20} {1,3}", match.Groups[2].Captures[ctr].Value,
                              match.Groups[4].Captures[ctr].Value);
      }
   }
}
// The example displays the following output:
//       Current temperatures:
//       Miami                 78
//       Chicago               62
//       New York              67
//       San Francisco         59
//       Seattle               58
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim input As String = "Miami,78;Chicago,62;New York,67;San Francisco,59;Seattle,58;"
        Dim pattern As String = "((\w+(\s\w+)*),(\d+);)+"
        Dim match As Match = Regex.Match(input, pattern)
        If match.Success Then
            Console.WriteLine("Current temperatures:")
            For ctr As Integer = 0 To match.Groups(2).Captures.Count - 1
                Console.WriteLine("{0,-20} {1,3}", match.Groups(2).Captures(ctr).Value, _
                                  match.Groups(4).Captures(ctr).Value)
            Next
        End If
    End Sub
End Module
' The example displays the following output:
'       Current temperatures:
'       Miami                 78
'       Chicago               62
'       New York              67
'       San Francisco         59
'       Seattle               58

A expressão regular é definida como mostrado na tabela a seguir.

Padrão Descrição
\w+ Fazer a correspondência a um ou mais caracteres de palavra.
(\s\w+)* Corresponder a zero ou mais ocorrências de um caractere de espaço em branco seguido por um ou mais caracteres de palavra. Este padrão corresponde a nomes de cidade com várias palavras. Este é o terceiro grupo de captura.
(\w+(\s\w+)*) Corresponder a um ou mais caracteres de palavra seguido por zero ou mais ocorrências de um caractere de espaço em branco e um ou mais caracteres de palavra. Este é o segundo grupo de captura.
, Corresponde a uma vírgula.
(\d+) Corresponder a um ou mais dígitos. Este é o quarto grupo de captura.
; Corresponder a um ponto e vírgula.
((\w+(\s\w+)*),(\d+);)+ Corresponder ao padrão de uma palavra seguida por qualquer palavra adicional seguida por uma vírgula, um ou mais dígitos e um ponto e vírgula, uma ou mais vezes. Este é o primeiro grupo de captura.

Confira também