Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Os quantificadores especificam quantas instâncias de um caractere, grupo ou classe de caracteres devem estar presentes na entrada para encontrar uma correspondência. A tabela a seguir lista os quantificadores com suporte no .NET:
Quantificador Greedy | Quantificador lento | Descrição |
---|---|---|
* |
*? |
Corresponde a zero ou mais vezes. |
+ |
+? |
Corresponde a uma ou mais vezes. |
? |
?? |
Corresponde a zero ou uma vez. |
{
n} |
{
n}? |
Corresponde exatamente a n vezes. |
{
n,} |
{
n,}? |
Corresponde a, pelo menos, n vezes. |
{
n, m} |
{
n, m}? |
Corresponde de n a m vezes. |
As quantidades n
e m
são constantes inteiras. Normalmente, os quantificadores são greedy. Eles fazem com que o mecanismo de expressões regulares corresponda a quantas ocorrências de padrões determinados forem possíveis. Acrescentar o caractere ?
a um quantificador torna-o lento. Isso faz com que o mecanismo de expressão regular corresponda ao menor número possível de ocorrências. Para obter uma descrição completa da diferença entre quantificadores greedy e lentos, confira a seção Quantificadores greedy e lentos mais adiante neste artigo.
Importante
Aninhar quantificadores, como o padrão de expressão regular (a*)*
, pode aumentar o número de comparações que o mecanismo de expressão regular precisa executar. O número de comparações pode aumentar como uma função exponencial do número de caracteres na cadeia de caracteres de entrada. Para saber mais sobre esse comportamento e suas soluções, veja Retrocesso.
Quantificadores em expressões regulares
As seções a seguir listam os quantificadores com suporte nas expressões regulares no .NET:
Observação
Se os caracteres *, +, ?, { e } forem encontrados em um padrão de expressão regular, o mecanismo de expressões regulares vai interpretá-los como quantificadores ou parte de constructos de quantificador, exceto se estiverem incluídos em uma classe de caracteres. Para interpretá-los como caracteres literais fora de uma classe de caracteres, você precisa fazer o escape, antecedendo-os com uma barra invertida. Por exemplo, a cadeia de caracteres \*
em um padrão de expressão regular é interpretada como um caractere asterisco (“*”) integral.
Corresponder a zero ou mais vezes: *
O quantificador *
corresponde ao elemento anterior zero ou mais vezes. É equivalente ao quantificador {0,}
.
*
é um quantificador Greedy, cujo equivalente lento é *?
.
O exemplo a seguir ilustra essa expressão regular. Cinco dos grupos de nove dígitos na cadeia de caracteres de entrada correspondem ao padrão e quatro (95
, 929
, 9219
e 9919
) não.
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($"'{match.Value}' found at position {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.
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.
O padrão de expressão regular é definido conforme mostrado na tabela a seguir:
Padrão | Descrição |
---|---|
\b |
Especifica que a correspondência deve começar em um limite de palavra. |
91* |
Corresponde a uma classe 9 seguida por zero ou mais 1 caracteres. |
9* |
Corresponde a zero ou mais caracteres 9 . |
\b |
Especifica que a correspondência deve terminar em um limite de palavra. |
Corresponder a um ou mais vezes: +
O quantificador +
corresponde ao elemento anterior uma ou mais vezes. É equivalente a {1,}
.
+
é um quantificador Greedy, cujo equivalente lento é +?
.
Por exemplo, a expressão regular \ban+\w*?\b
tenta corresponder a palavras inteiras que começam com a letra a
seguidas por uma ou mais instâncias da letra n
. O exemplo a seguir ilustra essa expressão regular. A expressão regular corresponde às palavras an
, annual
, announcement
e antique
, e não correspondem corretamente a autumn
e all
.
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($"'{match.Value}' found at position {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.
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.
O padrão de expressão regular é definido conforme mostrado na tabela a seguir:
Padrão | Descrição |
---|---|
\b |
Iniciar em um limite de palavra. |
an+ |
Corresponde a um a seguido por um ou mais caracteres n . |
\w*? |
Corresponde a um caractere de palavra zero ou mais vezes, mas o menor número de vezes possível. |
\b |
Terminar em um limite de palavra. |
Corresponder a zero ou uma vez: ?
O quantificador ?
corresponde ao elemento anterior zero ou uma vez. É equivalente a {0,1}
.
?
é um quantificador Greedy, cujo equivalente lento é ??
.
Por exemplo, a expressão regular \ban?\b
tenta corresponder a palavras inteiras que começam com a letra a
seguidas por zero ou uma instância da letra n
. Em outras palavras, ele tenta corresponder às palavras a
e an
. O exemplo a seguir ilustra essa expressão regular:
string pattern = @"\ban?\b";
string input = "An amiable animal with a large snout and an animated nose.";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
Console.WriteLine($"'{match.Value}' found at position {match.Index}.");
// The example displays the following output:
// 'An' found at position 0.
// 'a' found at position 23.
// 'an' found at position 42.
Dim pattern As String = "\ban?\b"
Dim input As String = "An amiable animal with a large snout 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.
O padrão de expressão regular é definido conforme mostrado na tabela a seguir:
Padrão | Descrição |
---|---|
\b |
Iniciar em um limite de palavra. |
an? |
Corresponde a um a seguido por zero ou um caractere n . |
\b |
Terminar em um limite de palavra. |
Corresponder exatamente a n vezes: {n}
O quantificador {
n}
corresponde ao elemento anterior exatamente n vezes, em que n é qualquer inteiro.
{
n}
é um quantificador Greedy cujo equivalente lento é {
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 por três dígitos decimais seguidos por um limite de palavra. O exemplo a seguir ilustra essa expressão regular:
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($"'{match.Value}' found at position {match.Index}.");
// The example displays the following output:
// '103,524' found at position 14.
// '106,971' found at position 45.
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.
O padrão de expressão regular é definido conforme 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} |
Corresponde a três dígitos decimais. |
\b |
Terminar em um limite de palavra. |
Corresponder a pelo menos n vezes: {n,}
O quantificador {
n,}
corresponde ao elemento anterior pelo menos n vezes, em que n é qualquer inteiro.
{
n,}
é um quantificador Greedy cujo equivalente lento é {
n,}?
.
Por exemplo, a expressão regular \b\d{2,}\b\D+
tenta corresponder a um limite de palavra seguido por 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. A expressão regular não corresponde à frase "7 days"
porque contém apenas um dígito decimal, mas corresponde com êxito às frases "10 weeks"
e "300 years"
.
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($"'{match.Value}' found at position {match.Index}.");
// The example displays the following output:
// '10 weeks, ' found at position 8.
// '300 years' found at position 18.
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.
O padrão de expressão regular é definido conforme 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 uma casa não decimal. |
Corresponder entre n e m vezes: {n,m}
O quantificador {
n,
m}
corresponde ao elemento anterior pelo menos n vezes, mas não mais de m vezes, em que n e m são inteiros.
{
n,
m}
é um quantificador Greedy cujo equivalente lento é {
n,
m}?
.
No exemplo a seguir, a expressão regular (00\s){2,4}
tenta corresponder a entre duas e quatro ocorrências de dois dígitos zero seguidos por um espaço. A parte final da cadeia de caracteres de entrada inclui esse padrão de cinco vezes em vez de no máximo quatro. No entanto, apenas a parte inicial dessa subcadeia de caracteres (até o espaço e o quinto par de zeros) corresponde ao padrão de expressão regular.
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($"'{match.Value}' found at position {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.
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.
Corresponder a zero ou mais vezes (correspondência lenta): *?
O quantificador *?
corresponde ao elemento anterior zero ou mais vezes, mas o menor número de vezes possível. É a contraparte lenta do quantificador greedy *
.
No exemplo a seguir, a expressão regular \b\w*?oo\w*?\b
corresponde a todas as palavras que contêm a cadeia de caracteres oo
.
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($"'{match.Value}' found at position {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.
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.
O padrão de expressão regular é definido conforme 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 o menor número de caracteres possível. |
oo |
Corresponde à cadeia de caracteres oo . |
\w*? |
Corresponde a zero ou mais caracteres de palavra, mas o menor número de caracteres possível. |
\b |
Terminar em um limite de palavra. |
Corresponder a uma ou mais vezes (correspondência lenta): +?
O quantificador +?
corresponde ao elemento anterior uma ou mais vezes, mas o menor número de vezes possível. É a contraparte lenta do quantificador greedy +
.
Por exemplo, a expressão regular \b\w+?\b
corresponde a um ou mais caracteres separados por limites de palavra. O exemplo a seguir ilustra essa expressão regular:
string pattern = @"\b\w+?\b";
string input = "Aa Bb Cc Dd Ee Ff";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine($"'{match.Value}' found at position {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.
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.
Corresponder a zero ou uma vez (correspondência lenta): ??
O quantificador ??
corresponde ao elemento anterior zero ou uma vez, mas o menor número de vezes possível. É a contraparte lenta do quantificador greedy ?
.
Por exemplo, a expressão regular ^\s*(System.)??Console.Write(Line)??\(??
tenta corresponder às cadeias de caracteres Console.Write
ou Console.WriteLine
. A cadeia de caracteres também pode incluir System.
antes de Console
, e pode ser seguida por um parêntese de abertura. A cadeia de caracteres deve estar no início de uma linha, embora possa ser antecedida por espaço em branco. O exemplo a seguir ilustra essa expressão regular:
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($"'{match.Value}' found at position {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.
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.
O padrão de expressão regular é definido conforme 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 ocorrência da cadeia de caracteres System. . |
Console.Write |
Corresponde à cadeia de caracteres Console.Write . |
(Line)?? |
Corresponde a zero ou uma ocorrência da cadeia de caracteres Line . |
\(?? |
Corresponde a zero ou uma ocorrência do parêntese de abertura. |
Corresponder exatamente a n vezes (correspondência lenta): {n}?
O quantificador {
n}?
corresponde ao elemento anterior exatamente n
vezes, em que n é qualquer inteiro. É a contraparte lenta do quantificador greedy {
n}
.
No exemplo a seguir, a expressão regular \b(\w{3,}?\.){2}?\w{3,}?\b
é usada para identificar um endereço web. A expressão corresponde a www.microsoft.com
e msdn.microsoft.com
, mas não corresponde a mywebsite
ou mycompany.com
.
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($"'{match.Value}' found at position {match.Index}.");
// The example displays the following output:
// 'www.microsoft.com' found at position 0.
// 'msdn.microsoft.com' found at position 18.
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.
O padrão de expressão regular é definido conforme mostrado na tabela a seguir:
Padrão | Descrição |
---|---|
\b |
Iniciar em um limite de palavra. |
(\w{3,}?\.) |
Corresponde a pelo menos três caracteres de palavra, mas o menor número de caracteres possível, seguido por um caractere de ponto. Esse padrão é o primeiro grupo de captura. |
(\w{3,}?\.){2}? |
Corresponde ao padrão no primeiro grupo duas vezes, mas o menor número de vezes possível. |
\b |
Termina a correspondência em um limite de palavra. |
Corresponder a pelo menos n vezes (correspondência lenta): {n,}?
O quantificador {
n,}?
corresponde ao elemento anterior pelo menos n
vezes, em que n é qualquer inteiro, mas o menor número de vezes possível. É a contraparte lenta do quantificador greedy {
n,}
.
Veja o exemplo do quantificador {
n}?
na seção anterior para obter uma ilustração. A expressão regular nesse exemplo usa o quantificador {
n,}
para corresponder a uma cadeia de caracteres que tem, pelo menos, três caracteres seguidos por um ponto final.
Corresponder entre n e m vezes (correspondência lenta): {n,m}?
O quantificador {
n,
m}?
corresponde ao elemento anterior entre n
e m
vezes, em que n e m são inteiros, mas o menor número de vezes possível. É o equivalente lento do quantificador greedy {
n,
m}
.
No exemplo a seguir, a expressão regular \b[A-Z](\w*?\s*?){1,10}[.!?]
corresponde a frases que contêm entre uma e dez palavras. Corresponde a todas as frases na cadeia de caracteres de entrada, exceto por uma frase que contém 18 palavras.
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($"'{match.Value}' found at position {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.
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.
O padrão de expressão regular é definido conforme mostrado na tabela a seguir:
Padrão | Descrição |
---|---|
\b |
Iniciar em um limite de palavra. |
[A-Z] |
Corresponde a um caractere maiúscula de A a Z. |
(\w*?\s*?) |
Corresponde a zero ou mais caracteres de palavra, seguidos por um ou mais caracteres de espaço em branco, mas o menor número de vezes possível. Esse padrão é o primeiro grupo de captura. |
{1,10} |
Corresponde ao padrão anterior entre 1 e 10 vezes. |
[.!?] |
Corresponde a qualquer um dos caracteres de pontuação . , ! ou ? . |
Quantificadores Greedy e lentos
Alguns quantificadores têm duas versões:
Uma versão Greedy.
Um quantificador Greedy tenta corresponder a um elemento tantas vezes quanto possível.
Uma versão não Greedy (ou lenta).
Um quantificador não Greedy tenta corresponder a um elemento o menor número de vezes possível. Você pode transformar um quantificador greedy em um quantificador lento adicionando um
?
.
Considere uma expressão regular que se destina a extrair os últimos quatro dígitos de uma cadeia de caracteres de números, como um número de cartão de crédito. A versão da expressão regular que usa o quantificador Greedy *
é \b.*([0-9]{4})\b
. No entanto, se uma cadeia de caracteres contiver dois números, essa expressão regular corresponde aos últimos quatro dígitos do segundo número, como mostra o exemplo a seguir:
string greedyPattern = @"\b.*([0-9]{4})\b";
string input1 = "1112223333 3992991999";
foreach (Match match in Regex.Matches(input1, greedyPattern))
Console.WriteLine($"Account ending in ******{match.Groups[1].Value}.");
// The example displays the following output:
// Account ending in ******1999.
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.
A expressão regular não corresponde ao primeiro número porque o quantificador *
tenta corresponder ao elemento anterior tantas vezes quanto possível em toda a cadeia de caracteres e encontra sua correspondência no final da cadeia de caracteres.
Esse comportamento não é o desejado. Em vez disso, é possível usar o quantificador lento *?
para extrair dígitos de ambos os números, como mostra o exemplo a seguir:
string lazyPattern = @"\b.*?([0-9]{4})\b";
string input2 = "1112223333 3992991999";
foreach (Match match in Regex.Matches(input2, lazyPattern))
Console.WriteLine($"Account ending in ******{match.Groups[1].Value}.");
// The example displays the following output:
// Account ending in ******3333.
// Account ending in ******1999.
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.
Na maioria dos casos, expressões regulares com quantificadores Greedy e lentos retornam as mesmas correspondências. Geralmente retornam resultados diferentes quando são usadas com o metacaractere curinga (.
), que corresponde a qualquer caractere.
Quantificadores e correspondências vazias
Os quantificadores *
, +
e {
n,
m}
e seus equivalentes lentos nunca se repetem depois de uma correspondência vazia quando o número mínimo de capturas foi encontrado. Essa regra impede que quantificadores entrem em loops infinitos em correspondências vazias de subexpressão quando o número máximo de capturas de grupo possíveis é infinito ou quase infinito.
Por exemplo, o código a seguir mostra o resultado de uma chamada para o método Regex.Match com o padrão de expressão regular (a?)*
que corresponde a zero ou a um caractere a
zero ou mais vezes. Observe que o grupo de captura único captura cada a
bem como String.Empty, mas que não há uma segunda correspondência vazia, porque a primeira correspondência vazia faz com que o quantificador pare de se repetir.
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: '{match.Value}' at index {match.Index}");
if (match.Groups.Count > 1) {
GroupCollection groups = match.Groups;
for (int grpCtr = 1; grpCtr <= groups.Count - 1; grpCtr++) {
Console.WriteLine($" Group {grpCtr}: '{groups[grpCtr].Value}' at index {groups[grpCtr].Index}");
int captureCtr = 0;
foreach (Capture capture in groups[grpCtr].Captures) {
captureCtr++;
Console.WriteLine($" Capture {captureCtr}: '{capture.Value}' at index {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
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
Para ver a diferença prática entre um grupo de captura que define um número mínimo e máximo de captura e um 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 na tabela a seguir:
Padrão | Descrição |
---|---|
(a\1 |
Faça qualquer correspondência a a juntamente com o valor do primeiro grupo de captura … |
|(?(1) |
… ou teste se o primeiro grupo de captura foi definido. O constructo (?(1) não define um grupo de captura. |
\1)) |
Se o primeiro grupo capturado existir, faça uma correspondência ao valor. Se o grupo não existir, será correspondente a String.Empty. |
A primeira expressão regular tenta corresponder a esse padrão entre zero e duas vezes; a segunda, exatamente duas vezes. Como o primeiro padrão atinge seu número mínimo de capturas com sua primeira captura de String.Empty, ele nunca se repete para tentar corresponder a a\1
. O quantificador {0,2}
permite apenas correspondências vazias na última iteração. Por outro lado, a segunda expressão regular corresponde a a
porque avalia a\1
uma segunda vez. O número mínimo de iterações, 2, força o mecanismo a repetir após uma correspondência vazia.
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: {pattern}");
Match match = Regex.Match(input, pattern);
Console.WriteLine($"Match: '{match.Value}' at position {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: {groupCtr}: '{group.Value}' at position {group.Index}.");
int captureCtr = 0;
foreach (Capture capture in group.Captures) {
captureCtr++;
Console.WriteLine($" Capture: {captureCtr}: '{capture.Value}' at position {capture.Index}.");
}
}
}
Console.WriteLine();
pattern = @"(a\1|(?(1)\1)){2}";
Console.WriteLine($"Regex pattern: {pattern}");
match = Regex.Match(input, pattern);
Console.WriteLine($"Matched '{match.Value}' at position {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: {groupCtr}: '{group.Value}' at position {group.Index}.");
int captureCtr = 0;
foreach (Capture capture in group.Captures) {
captureCtr++;
Console.WriteLine($" Capture: {captureCtr}: '{capture.Value}' at position {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.
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.