Partilhar via


Quantificadores

Quantificadores especificam quantas instâncias de um caractere, o grupo ou a classe de caracteres devem estar presentes na entrada corresponde a ser encontrado. A tabela a seguir lista os quantificadores suportados pelo.NET Framework.

Quantificador greedy

Quantificador lazy

Descrição

*

*?

Corresponde a zero ou mais vezes.

+

+?

Corresponde a uma ou mais vezes.

?

??

Corresponde a zero ou uma vez.

{n}

{n}?

Coincidir exatamente n vezes.

{n,}

{n,}?

Corresponde a pelo menos n vezes.

{n,m}

{n,m}?

Fazer a correspondência em n para m vezes.

As n e m quantidades são constantes inteiras. Normalmente, os quantificadores são greedy; eles fazer com que o mecanismo de expressões regulares corresponder à quantas ocorrências dos padrões específicos quanto possível. Acrescentando o ? o caractere de um quantificador torna lenta; ele faz com que o mecanismo de expressões regulares coincidir com o menor número de ocorrências possível. Para obter uma descrição completa da diferença entre quantificadores greedy e lentas, consulte a seção Greedy e quantificadores preguiçoso posteriormente neste tópico.

Observação importanteImportante

Quantificadores de aninhamento (por exemplo, como o padrão de expressão regular (a*)* oferece) pode aumentar o número de comparações que deve executar o mecanismo de expressão regular, como uma função exponencial do número de caracteres na seqüência de caracteres de entrada.Para obter mais informações sobre esse comportamento e suas soluções alternativas, consulte Retrocedendo.

Quantificadores de expressão regular

As seções a seguir listam os quantificadores suportados pelo.Expressões regulares do NET Framework.

Observação

Se o *, +,?, {, e} caracteres são encontrados em um padrão de expressão regular, o mecanismo de expressão regular interpreta como quantificadores ou parte de construções de quantificador a menos que sejam incluídas em um classe de caracteres.Para interpretar esses como caracteres literais fora de uma classe de caractere, escape-los a precedendo-los com uma barra invertida.Por exemplo, a seqüência de caracteres \* em uma expressão regular padrão é interpretado como um asterisco literal ("*") caracteres.

Corresponde a Zero ou mais vezes: *

O * quantificador coincide com o elemento anterior zero ou mais vezes. Ela é equivalente a {0,} quantificador. *é um quantificador greedy cujo equivalente lenta é *?.

O exemplo a seguir ilustra essa expressão regular. De nove dígitos na seqüência de entrada, cinco coincidir com o padrão e quatro (95, 929, 9129, e 9919) fazer não.

Dim pattern As String = "\b91*9*\b"   
Dim input As String = "99 95 919 929 9119 9219 999 9919 91119"
For Each match As Match In Regex.Matches(input, pattern)
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next     
' The example displays the following output:   
'       '99' found at position 0.
'       '919' found at position 6.
'       '9119' found at position 14.
'       '999' found at position 24.
'       '91119' found at position 33.
string pattern = @"\b91*9*\b";   
string input = "99 95 919 929 9119 9219 999 9919 91119";
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:   
//       '99' found at position 0.
//       '919' found at position 6.
//       '9119' found at position 14.
//       '999' found at position 24.
//       '91119' found at position 33.

O padrão de expressão regular é definido como mostrado na tabela a seguir.

Padrão

Descrição

\b

Iniciar em um limite de palavra.

91*

Coincidir com "9" seguido de zero ou mais "1" caracteres.

9*

Corresponde a zero ou mais "9" caracteres.

\b

Terminar em um limite de palavra.

Corresponder a um ou mais vezes: +

O + quantificador coincide com o elemento anterior uma ou mais vezes. É equivalente a {1,}. +é um quantificador greedy cujo equivalente lenta é +?.

Por exemplo, a expressão regular \ban+\w*?\b tenta coincidir palavras inteiras que começam com a letra a seguido de uma ou mais ocorrências da letra n. O exemplo a seguir ilustra essa expressão regular. A expressão regular corresponde as palavras an, annual, announcement, e antiquee corretamente não corresponder à autumn e all.

Dim pattern As String = "\ban+\w*?\b"

Dim input As String = "Autumn is a great time for an annual announcement to all antique collectors."
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next   
' The example displays the following output:   
'       'an' found at position 27.
'       'annual' found at position 30.
'       'announcement' found at position 37.
'       'antique' found at position 57.      
string pattern = @"\ban+\w*?\b";

string input = "Autumn is a great time for an annual announcement to all antique collectors.";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);

// The example displays the following output:   
//       'an' found at position 27.
//       'annual' found at position 30.
//       'announcement' found at position 37.
//       'antique' found at position 57.      

O padrão de expressão regular é definido como mostrado na tabela a seguir.

Padrão

Descrição

\b

Iniciar em um limite de palavra.

an+

Correspondência de um "a" seguido por um ou mais "n" caracteres.

\w*?

Corresponde a um caractere de palavra zero ou mais vezes, mas, como algumas vezes possível.

\b

Terminar em um limite de palavra.

Corresponde a Zero ou uma vez: ?

O ? quantificador coincide com o tempo de elemento zero ou um anterior. É equivalente a {0,1}. ?é um quantificador greedy cujo equivalente lenta é ??.

Por exemplo, a expressão regular \ban?\b tenta coincidir palavras inteiras que começam com a letra a seguido de zero ou um de ocorrências da letra n. Em outras palavras, ele tenta corresponder a palavras a e an. O exemplo a seguir ilustra essa expressão regular.

Dim pattern As String = "\ban?\b"
Dim input As String = "An amiable animal with a large snount and an animated nose."
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next  
' The example displays the following output:   
'       'An' found at position 0.
'       'a' found at position 23.
'       'an' found at position 42.
string pattern = @"\ban?\b";
string input = "An amiable animal with a large snount and an animated nose.";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);

// The example displays the following output:   
//        'An' found at position 0.
//        'a' found at position 23.
//        'an' found at position 42.

O padrão de expressão regular é definido como mostrado na tabela a seguir.

Padrão

Descrição

\b

Iniciar em um limite de palavra.

an?

Correspondência de um "a" seguido de zero ou um "n" caractere.

\b

Terminar em um limite de palavra.

Coincidir exatamente a n vezes: {n}

O {n} quantificador coincide com o elemento anterior exatamente n vezes, onde n é qualquer número inteiro. {n} é um quantificador greedy cujo equivalente lenta é {n}?.

Por exemplo, a expressão regular \b\d+\,\d{3}\b tenta corresponder a um limite de palavra, seguido por um ou mais dígitos decimais, seguidos de três dígitos decimais, seguidos por um limite de palavra. O exemplo a seguir ilustra essa expressão regular.

Dim pattern As String = "\b\d+\,\d{3}\b"
Dim input As String = "Sales totaled 103,524 million in January, " + _
                      "106,971 million in February, but only " + _
                      "943 million in March."
For Each match As Match In Regex.Matches(input, pattern)
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next     
' The example displays the following output:   
'       '103,524' found at position 14.
'       '106,971' found at position 45.
string pattern = @"\b\d+\,\d{3}\b";
string input = "Sales totaled 103,524 million in January, " + 
                      "106,971 million in February, but only " + 
                      "943 million in March.";
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:   
//        '103,524' found at position 14.
//        '106,971' found at position 45.

O padrão de expressão regular é definido como mostrado na tabela a seguir.

Padrão

Descrição

\b

Iniciar em um limite de palavra.

\d+

Corresponde a um ou mais dígitos decimais.

\,

Corresponde a um caractere de vírgula.

\d{3}

Coincide com três dígitos decimais.

\b

Terminar em um limite de palavra.

Corresponde a pelo menos n vezes: {n}

O {n,} quantificador coincide com o elemento anterior pelo menos n vezes, onde n é qualquer número inteiro. {n,} é um quantificador greedy cujo equivalente lenta é {n}?.

Por exemplo, a expressão regular \b\d{2,}\b\D+ tenta corresponder a um limite de palavra, seguido pelo menos dois dígitos seguidos por um limite de palavra e um caractere não dígito. O exemplo a seguir ilustra essa expressão regular. Falha de expressão regular coincidir com a frase "7 days" porque ele contém apenas um dígito decimal, mas coincide com as frases com êxito "10 weeks and 300 years".

 Dim pattern As String = "\b\d{2,}\b\D+"  
 Dim input As String = "7 days, 10 weeks, 300 years"
For Each match As Match In Regex.Matches(input, pattern)
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next 
' The example displays the following output:
'       '10 weeks, ' found at position 8.
'       '300 years' found at position 18.
string pattern = @"\b\d{2,}\b\D+";   
string input = "7 days, 10 weeks, 300 years";
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:
//        '10 weeks, ' found at position 8.
//        '300 years' found at position 18.

O padrão de expressão regular é definido como mostrado na tabela a seguir.

Padrão

Descrição

\b

Iniciar em um limite de palavra.

\d{2,}

Corresponde a pelo menos dois dígitos decimais.

\b

Corresponde a um limite de palavra.

\D+

Corresponde a pelo menos um dígito de decimal com ponto.

Correspondência entre os horários de n e m: {n, m}

O {n,m} quantificador coincide com o elemento anterior pelo menos n vezes, mas não mais de m vezes, onde n e m são números inteiros. {n,m} é um quantificador greedy cujo equivalente lenta é {n,m}?.

No exemplo a seguir, a expressão regular (00\s){2,4} tenta corresponder entre dois e quatro de ocorrências de dois zero dígitos seguidos de um espaço. Observe que a parte final da seqüência de entrada inclui este padrão de cinco vezes em vez de um máximo de quatro. No entanto, apenas a parte inicial deste substring (até o espaço e o quinto par de zeros) coincide com o padrão de expressão regular.

Dim pattern As String = "(00\s){2,4}"
Dim input As String = "0x00 FF 00 00 18 17 FF 00 00 00 21 00 00 00 00 00"
For Each match As Match In Regex.Matches(input, pattern)
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next 
' The example displays the following output:
'       '00 00 ' found at position 8.
'       '00 00 00 ' found at position 23.
'       '00 00 00 00 ' found at position 35.
string pattern = @"(00\s){2,4}";
string input = "0x00 FF 00 00 18 17 FF 00 00 00 21 00 00 00 00 00";
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:
//        '00 00 ' found at position 8.
//        '00 00 00 ' found at position 23.
//        '00 00 00 00 ' found at position 35.

Corresponde a Zero ou mais vezes (correspondência lenta): *?

O *? quantificador coincide com o elemento anterior zero ou mais vezes, mas, como algumas vezes como possível. É a contraparte lenta do que o quantificador greedy *.

No exemplo a seguir, a expressão regular \b\w*?oo\w*?\b corresponde a todas as palavras que contêm a seqüência de caracteres oo.

 Dim pattern As String = "\b\w*?oo\w*?\b"
 Dim input As String = "woof root root rob oof woo woe"
 For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
 Next 
 ' The example displays the following output:
'       'woof' found at position 0.
'       'root' found at position 5.
'       'root' found at position 10.
'       'oof' found at position 19.
'       'woo' found at position 23.
 string pattern = @"\b\w*?oo\w*?\b";
 string input = "woof root root rob oof woo woe";
 foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);

 //  The example displays the following output:
//        'woof' found at position 0.
//        'root' found at position 5.
//        'root' found at position 10.
//        'oof' found at position 19.
//        'woo' found at position 23.

O padrão de expressão regular é definido como mostrado na tabela a seguir.

Padrão

Descrição

\b

Iniciar em um limite de palavra.

\w*?

Corresponde a zero ou mais caracteres de palavra, mas como alguns caracteres possíveis.

oo

Coincide com a seqüência de caracteres "oo".

\w*?

Corresponde a zero ou mais caracteres de palavra, mas como alguns caracteres possíveis.

\b

Terminar em um limite de palavra.

Corresponde a um ou mais vezes (correspondência lenta): +?

O +? quantificador coincide com o elemento anterior de uma ou mais vezes, mas, como algumas vezes como possível. É a contraparte lenta do que o quantificador greedy +.

Por exemplo, a expressão regular \b\w+?\b corresponde a um ou mais caracteres separados por limites do word. O exemplo a seguir ilustra essa expressão regular.

 Dim pattern As String = "\b\w+?\b"
 Dim input As String = "Aa Bb Cc Dd Ee Ff"
For Each match As Match In Regex.Matches(input, pattern)
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next 
' The example displays the following output:
'       'Aa' found at position 0.
'       'Bb' found at position 3.
'       'Cc' found at position 6.
'       'Dd' found at position 9.
'       'Ee' found at position 12.
'       'Ff' found at position 15.
string pattern = @"\b\w+?\b";
string input = "Aa Bb Cc Dd Ee Ff";
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:
//        'Aa' found at position 0.
//        'Bb' found at position 3.
//        'Cc' found at position 6.
//        'Dd' found at position 9.
//        'Ee' found at position 12.
//        'Ff' found at position 15.

Corresponde a Zero ou uma vez (correspondência lenta): ??

O ?? quantificador corresponde à hora de elemento zero ou uma anterior, mas como algumas vezes como possível. É a contraparte lenta do que o quantificador greedy ?.

Por exemplo, a expressão regular ^\s*(System.)??Console.Write(Line)??\(?? tenta coincidir as seqüências de caracteres "Console. Write" ou "Console. WriteLine". A seqüência de caracteres também pode incluir o "Sistema". antes de "Console" e ele podem ser seguido por um parêntese de abertura. A seqüência de caracteres deve ser no início de uma linha, embora ele possa ser precedido por espaço em branco. O exemplo a seguir ilustra essa expressão regular.

Dim pattern As String = "^\s*(System.)??Console.Write(Line)??\(??"
Dim input As String = "System.Console.WriteLine(""Hello!"")" + vbCrLf + _
                      "Console.Write(""Hello!"")" + vbCrLf + _
                      "Console.WriteLine(""Hello!"")" + vbCrLf + _
                      "Console.ReadLine()" + vbCrLf + _
                      "   Console.WriteLine"
For Each match As Match In Regex.Matches(input, pattern, _
                                         RegexOptions.IgnorePatternWhitespace Or RegexOptions.IgnoreCase Or RegexOptions.MultiLine)
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next 
' The example displays the following output:
'       'System.Console.Write' found at position 0.
'       'Console.Write' found at position 36.
'       'Console.Write' found at position 61.
'       '   Console.Write' found at position 110.
string pattern = @"^\s*(System.)??Console.Write(Line)??\(??";
string input = "System.Console.WriteLine(\"Hello!\")\n" + 
                      "Console.Write(\"Hello!\")\n" + 
                      "Console.WriteLine(\"Hello!\")\n" + 
                      "Console.ReadLine()\n" + 
                      "   Console.WriteLine";
foreach (Match match in Regex.Matches(input, pattern, 
                                      RegexOptions.IgnorePatternWhitespace | 
                                      RegexOptions.IgnoreCase | 
                                      RegexOptions.Multiline))
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);

//  The example displays the following output:
//        'System.Console.Write' found at position 0.
//        'Console.Write' found at position 36.
//        'Console.Write' found at position 61.
//        '   Console.Write' found at position 110.

O padrão de expressão regular é definido como mostrado na tabela a seguir.

Padrão

Descrição

^

Corresponde ao início do fluxo de entrada.

\s*

Corresponde a zero ou mais caracteres de espaço em branco.

(System.)??

Corresponde a zero ou uma de ocorrência da seqüência do "Sistema".

Console.Write

Coincide com a seqüência de caracteres "Console. Write".

(Line)??

Corresponde a zero ou uma de ocorrência da seqüência de caracteres "Linha".

\(??

Corresponde à ocorrência zero ou um parêntese de abertura.

Coincidir exatamente a n vezes (correspondência lenta): {n}?

O {n}? quantificador coincide com o elemento anterior exatamente n vezes, onde n é qualquer número inteiro. É a contraparte lenta do que o quantificador greedy {n}+.

No exemplo a seguir, a expressão regular \b(\w{3,}?\.){2}?\w{3,}?\b é usado para identificar um endereço de site da Web. Observe que corresponde ao "www.microsoft.com" e "msdn.microsoft.com", mas não não corresponde ao "Meu_Site" ou "mycompany.com".

 Dim pattern As String = "\b(\w{3,}?\.){2}?\w{3,}?\b"
 Dim input As String = "www.microsoft.com msdn.microsoft.com mywebsite mycompany.com"
For Each match As Match In Regex.Matches(input, pattern)
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next     
' The example displays the following output:
'       'www.microsoft.com' found at position 0.
'       'msdn.microsoft.com' found at position 18.
string pattern = @"\b(\w{3,}?\.){2}?\w{3,}?\b";
string input = "www.microsoft.com msdn.microsoft.com mywebsite mycompany.com";
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:
//        'www.microsoft.com' found at position 0.
//        'msdn.microsoft.com' found at position 18.

O padrão de expressão regular é definido como mostrado na tabela a seguir.

Padrão

Descrição

\b

Iniciar em um limite de palavra.

(\w{3,}? \.)

Corresponde a pelo menos 3 caracteres de palavra, mas como alguns caracteres possíveis, seguido por um ponto ou o caractere de ponto. Este é o primeiro grupo de capturando.

(\w{3,}? \.){2}?

Coincide com o padrão no primeiro grupo de duas vezes, mas algumas vezes possível.

\b

Finalize a correspondência de um limite de palavra.

Corresponde a pelo menos n vezes (correspondência lenta): {n,}?

O {n,}? quantificador coincide com o elemento anterior pelo menos n vezes, onde n é qualquer número inteiro, mas, como algumas vezes possível. É a contraparte lenta do que o quantificador greedy {n,}.

Consulte o exemplo para o {n}? quantificador na seção anterior para obter uma ilustração. A expressão regular esse exemplo usa o {n,} quantificador para coincidir com uma seqüência que tenha pelo menos três caracteres, seguido por um período.

Correspondência entre n e m vezes (correspondência lenta): {n, m}?

O {n,m}? quantificador coincide com o elemento anterior entre n e m vezes, onde n e m são inteiros, mas, como algumas vezes possível. É a contraparte lenta do que o quantificador greedy {n,m}.

No exemplo a seguir, a expressão regular \b[A-Z](\w*\s+){1,10}?[.!?] corresponde a sentenças que contêm entre um e dez palavras. Corresponde a todas as frases na seqüência de entrada, exceto para uma sentença que contenha 18 palavras.

Dim pattern As String = "\b[A-Z](\w*\s?){1,10}?[.!?]"
Dim input As String = "Hi. I am writing a short note. Its purpose is " + _
                      "to test a regular expression that attempts to find " + _
                      "sentences with ten or fewer words. Most sentences " + _
                      "in this note are short."
For Each match As Match In Regex.Matches(input, pattern)
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next 
' The example displays the following output:
'       'Hi.' found at position 0.
'       'I am writing a short note.' found at position 4.
'       'Most sentences in this note are short.' found at position 132.
string pattern = @"\b[A-Z](\w*?\s*?){1,10}[.!?]";
string input = "Hi. I am writing a short note. Its purpose is " + 
                      "to test a regular expression that attempts to find " + 
                      "sentences with ten or fewer words. Most sentences " + 
                      "in this note are short.";
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:
//        'Hi.' found at position 0.
//        'I am writing a short note.' found at position 4.
//        'Most sentences in this note are short.' found at position 132.

O padrão de expressão regular é definido como mostrado na tabela a seguir.

Padrão

Descrição

\b

Iniciar em um limite de palavra.

[A-Z]

Corresponde a um caractere maiúsculo, de À Z.

(\w*\s+)

Corresponde a zero ou mais caracteres alfabéticos, seguidos por um ou mais caracteres de espaço em branco. Este é o primeiro grupo de captura.

{1,10}?

Coincide com o padrão anterior entre os horários de 1 a 10, mas algumas vezes possível.

[.!?]

Corresponder a qualquer um dos caracteres de pontuação ".","!", ou "?".

Quantificadores greedy e lentas

Um número dos quantificadores tem duas versões:

  • Uma versão greedy.

    Um quantificador greedy tenta corresponder a um elemento quantas vezes forem possíveis.

  • Uma versão não greedy (ou lenta).

    Um quantificador greedy tenta corresponder a um elemento como algumas vezes possível. Você pode transformar um quantificador greedy no quantificador lazy simplesmente adicionando um ?.

Considere a possibilidade de uma expressão regular simple que se destina a extrair os quatro últimos dígitos de uma seqüência de números como, por exemplo, um número de cartão de crédito. A versão da expressão regular que usa o * o quantificador greedy é \b.*([0-9]{4})\b. No entanto, se uma seqüência contém dois números, essa expressão regular corresponde os quatro últimos dígitos do segundo número somente, como mostra o exemplo a seguir.

Dim greedyPattern As String = "\b.*([0-9]{4})\b"
Dim input1 As String = "1112223333 3992991999"
For Each match As Match In Regex.Matches(input1, greedypattern)
   Console.WriteLine("Account ending in ******{0}.", match.Groups(1).Value)
Next
' The example displays the following output:
'       Account ending in ******1999.
string greedyPattern = @"\b.*([0-9]{4})\b";
string input1 = "1112223333 3992991999";
foreach (Match match in Regex.Matches(input1, greedyPattern))
   Console.WriteLine("Account ending in ******{0}.", match.Groups[1].Value);

// The example displays the following output:
//       Account ending in ******1999.

Falha de expressão regular coincidir com o primeiro número porque o * quantificador tenta corresponder o elemento anterior quantas vezes forem possíveis na cadeia de caracteres inteira, e então encontrar sua correspondência ao final da seqüência de caracteres.

Isso não é o comportamento desejado. Em vez disso, você pode usar o *?quantificador lazy para extrair os dígitos de dois números, como o exemplo a seguir mostra.

Dim lazyPattern As String = "\b.*?([0-9]{4})\b"
Dim input2 As String = "1112223333 3992991999"
For Each match As Match In Regex.Matches(input2, lazypattern)
   Console.WriteLine("Account ending in ******{0}.", match.Groups(1).Value)
Next     
' The example displays the following output:
'       Account ending in ******3333.
'       Account ending in ******1999.
string lazyPattern = @"\b.*?([0-9]{4})\b";
string input2 = "1112223333 3992991999";
foreach (Match match in Regex.Matches(input2, lazyPattern))
   Console.WriteLine("Account ending in ******{0}.", match.Groups[1].Value);

// The example displays the following output:
//       Account ending in ******3333.
//       Account ending in ******1999.

Na maioria dos casos, as expressões regulares com quantificadores greedy e lentas retornam as correspondências do mesmas. Mais comumente retornam resultados diferentes quando eles são usados com o caractere curinga (.) metacaractere, que corresponde ao caractere.

Quantificadores e Correspondências vazias

Os quantificadores *, +, e {n,m} e contrapartes preguiçosos repetir nunca após uma correspondência vazia quando o número mínimo de capturas foi encontrado. Essa regra impede que quantificadores inserindo loops infinitos correspondências de subexpressão vazio quando o número máximo de capturas de grupo possíveis é infinito ou quase infinita.

Por exemplo, o código a seguir mostra o resultado de uma chamada para o Regex.Match o método com o padrão de expressão regular (a?)*, que corresponde a zero ou um "a" caractere zero ou mais vezes. Observe que o único grupo de capturando captura a cada "a" Assim como String.Empty, mas que não há nenhuma correspondência segunda vazia, pois a primeira correspondência vazia faz com que o quantificador parar a repetição.

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim pattern As String = "(a?)*"
      Dim input As String = "aaabbb"
      Dim match As Match = Regex.Match(input, pattern)
      Console.WriteLine("Match: '{0}' at index {1}", 
                        match.Value, match.Index)
      If match.Groups.Count > 1 Then
         Dim groups As GroupCollection = match.Groups
         For grpCtr As Integer = 1 To groups.Count - 1
            Console.WriteLine("   Group {0}: '{1}' at index {2}", 
                              grpCtr, 
                              groups(grpCtr).Value,
                              groups(grpCtr).Index)
            Dim captureCtr As Integer = 0
            For Each capture As Capture In groups(grpCtr).Captures
               captureCtr += 1
               Console.WriteLine("      Capture {0}: '{1}' at index {2}", 
                                 captureCtr, capture.Value, capture.Index)
            Next
         Next 
      End If   
   End Sub
End Module
' The example displays the following output:
'       Match: 'aaa' at index 0
'          Group 1: '' at index 3
'             Capture 1: 'a' at index 0
'             Capture 2: 'a' at index 1
'             Capture 3: 'a' at index 2
'             Capture 4: '' at index 3
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = "(a?)*";
      string input = "aaabbb";
      Match match = Regex.Match(input, pattern);
      Console.WriteLine("Match: '{0}' at index {1}", 
                        match.Value, match.Index);
      if (match.Groups.Count > 1) {
         GroupCollection groups = match.Groups;
         for (int grpCtr = 1; grpCtr <= groups.Count - 1; grpCtr++) {
            Console.WriteLine("   Group {0}: '{1}' at index {2}", 
                              grpCtr, 
                              groups[grpCtr].Value,
                              groups[grpCtr].Index);
            int captureCtr = 0;
            foreach (Capture capture in groups[grpCtr].Captures) {
               captureCtr++;
               Console.WriteLine("      Capture {0}: '{1}' at index {2}", 
                                 captureCtr, capture.Value, capture.Index);
            }
         } 
      }   
   }
}
// The example displays the following output:
//       Match: 'aaa' at index 0
//          Group 1: '' at index 3
//             Capture 1: 'a' at index 0
//             Capture 2: 'a' at index 1
//             Capture 3: 'a' at index 2
//             Capture 4: '' at index 3

Para ver a diferença prática entre um grupo de captura que define um mínimo e um número máximo de capturas e que define um número fixo de capturas, considere os padrões de expressão regular (a\1|(?(1)\1)){0,2} e (a\1|(?(1)\1)){2}. Ambas as expressões regulares consistem em um único grupo de captura, que é definido como mostrado na tabela a seguir.

Padrão

Descrição

(a\1

Qualquer correspondência "a" juntamente com o valor do primeiro capturado grupo …

|(?(1)

… ou testar se o primeiro grupo capturado foi definido. (Observe que o (?(1) construção não define um grupo de captura.)

\1))

Se o primeiro grupo capturado existir, correspondente ao valor. Se o grupo não existir, o grupo corresponderá String.Empty.

A primeira expressão regular tenta corresponder a esse padrão entre tempos de zero e dois; o segundo, que exatamente duas vezes. Porque o primeiro padrão atinge seu número mínimo de capturas com sua primeira captura de String.Empty, nunca se repete para tentar corresponder a\1; o {0,2} quantificador permite correspondências somente vazias na última iteração. Em contraste, a segunda expressão regular corresponde ao "a" porque avalia a\1 uma segunda vez; o número mínimo de iterações, 2, força o mecanismo de Repetir após uma correspondência vazia.

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim pattern, input As String

      pattern = "(a\1|(?(1)\1)){0,2}"
      input = "aaabbb" 

      Console.WriteLine("Regex pattern: {0}", pattern)
      Dim match As Match = Regex.Match(input, pattern)
      Console.WriteLine("Match: '{0}' at position {1}.", 
                        match.Value, match.Index)
      If match.Groups.Count > 1 Then
         For groupCtr As Integer = 1 To match.Groups.Count - 1
            Dim group As Group = match.Groups(groupCtr)         
            Console.WriteLine("   Group: {0}: '{1}' at position {2}.", 
                              groupCtr, group.Value, group.Index)
            Dim captureCtr As Integer = 0
            For Each capture As Capture In group.Captures
               captureCtr += 1
               Console.WriteLine("      Capture: {0}: '{1}' at position {2}.", 
                                 captureCtr, capture.Value, capture.Index)
            Next   
         Next
      End If
      Console.WriteLine()

      pattern = "(a\1|(?(1)\1)){2}"
      Console.WriteLine("Regex pattern: {0}", pattern)
      match = Regex.Match(input, pattern)
         Console.WriteLine("Matched '{0}' at position {1}.", 
                           match.Value, match.Index)
      If match.Groups.Count > 1 Then
         For groupCtr As Integer = 1 To match.Groups.Count - 1
            Dim group As Group = match.Groups(groupCtr)         
            Console.WriteLine("   Group: {0}: '{1}' at position {2}.", 
                              groupCtr, group.Value, group.Index)
            Dim captureCtr As Integer = 0
            For Each capture As Capture In group.Captures
               captureCtr += 1
               Console.WriteLine("      Capture: {0}: '{1}' at position {2}.", 
                                 captureCtr, capture.Value, capture.Index)
            Next   
         Next
      End If
   End Sub
End Module
' The example displays the following output:
'       Regex pattern: (a\1|(?(1)\1)){0,2}
'       Match: '' at position 0.
'          Group: 1: '' at position 0.
'             Capture: 1: '' at position 0.
'       
'       Regex pattern: (a\1|(?(1)\1)){2}
'       Matched 'a' at position 0.
'          Group: 1: 'a' at position 0.
'             Capture: 1: '' at position 0.
'             Capture: 2: 'a' at position 0.
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern, input;

      pattern = @"(a\1|(?(1)\1)){0,2}";
      input = "aaabbb"; 

      Console.WriteLine("Regex pattern: {0}", pattern);
      Match match = Regex.Match(input, pattern);
      Console.WriteLine("Match: '{0}' at position {1}.", 
                        match.Value, match.Index);
      if (match.Groups.Count > 1) {
         for (int groupCtr = 1; groupCtr <= match.Groups.Count - 1; groupCtr++)
         {
            Group group = match.Groups[groupCtr];         
            Console.WriteLine("   Group: {0}: '{1}' at position {2}.", 
                              groupCtr, group.Value, group.Index);
            int captureCtr = 0;
            foreach (Capture capture in group.Captures) {
               captureCtr++;
               Console.WriteLine("      Capture: {0}: '{1}' at position {2}.", 
                                 captureCtr, capture.Value, capture.Index);
            }   
         }
      }
      Console.WriteLine();

      pattern = @"(a\1|(?(1)\1)){2}";
      Console.WriteLine("Regex pattern: {0}", pattern);
      match = Regex.Match(input, pattern);
         Console.WriteLine("Matched '{0}' at position {1}.", 
                           match.Value, match.Index);
      if (match.Groups.Count > 1) {
         for (int groupCtr = 1; groupCtr <= match.Groups.Count - 1; groupCtr++)
         {
            Group group = match.Groups[groupCtr];         
            Console.WriteLine("   Group: {0}: '{1}' at position {2}.", 
                              groupCtr, group.Value, group.Index);
            int captureCtr = 0;
            foreach (Capture capture in group.Captures) {
               captureCtr++;
               Console.WriteLine("      Capture: {0}: '{1}' at position {2}.", 
                                 captureCtr, capture.Value, capture.Index);
            }   
         }
      }
   }
}
// The example displays the following output:
//       Regex pattern: (a\1|(?(1)\1)){0,2}
//       Match: '' at position 0.
//          Group: 1: '' at position 0.
//             Capture: 1: '' at position 0.
//       
//       Regex pattern: (a\1|(?(1)\1)){2}
//       Matched 'a' at position 0.
//          Group: 1: 'a' at position 0.
//             Capture: 1: '' at position 0.
//             Capture: 2: 'a' at position 0.

Consulte também

Conceitos

Elementos de linguagem das expressões regulares

Retrocedendo

Histórico de alterações

Date

History

Motivo

Outubro de 2010

Adicionado "quantificadores e correspondências vazias" seção.

Aprimoramento de informações.