Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Os quantificadores especificam quantas instâncias de um caractere, grupo ou classe de caractere devem estar presentes na entrada para que uma correspondência seja encontrada. A tabela a seguir lista os quantificadores suportados pelo .NET:
Quantificador ganancioso | Quantificador preguiçoso | 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 pelo menos n vezes. |
{
n, O} |
{
n, O}? |
Jogos de n a m vezes. |
As quantidades n
e m
são constantes inteiras. Normalmente, os quantificadores são gananciosos. Eles fazem com que o mecanismo de expressão regular corresponda ao maior número possível de ocorrências de padrões específicos. Anexar o ?
personagem a um quantificador torna-o preguiçoso. 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 gananciosos e preguiçosos, consulte a seção Quantificadores gananciosos e preguiçosos mais adiante neste artigo.
Importante
Os quantificadores de aninhamento, como o padrão de expressão regular (a*)*
, podem aumentar o número de comparações que o mecanismo de expressão regular deve executar. O número de comparações pode aumentar como uma função exponencial do número de caracteres na cadeia de entrada. Para obter mais informações sobre esse comportamento e suas soluções alternativas, consulte Backtracking.
Quantificadores de Expressão Regular
As seções a seguir listam os quantificadores suportados pelas expressões regulares do .NET:
Nota
Se os caracteres *, +, ?, { e } forem encontrados em um padrão de expressão regular, o mecanismo de expressão regular os interpretará como quantificadores ou parte de construções quantificadoras, a menos que sejam incluídos em uma classe de caracteres. Para interpretá-los como caracteres literais fora de uma classe de caracteres, você deve escapar deles precedendo-os com uma barra invertida. Por exemplo, a cadeia de caracteres \*
em um padrão de expressão regular é interpretada como um caractere de asterisco literal ("*").
Combinar zero ou mais vezes: *
O *
quantificador corresponde ao elemento anterior zero ou mais vezes. É equivalente ao quantificador {0,}
.
*
é um quantificador ganancioso cujo equivalente preguiçoso é *?
.
O exemplo a seguir ilustra essa expressão regular. Cinco dos nove grupos de 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 palavras. |
91* |
Corresponde a um 9 seguido por zero ou mais 1 caracteres. |
9* |
Corresponde a zero ou mais 9 caracteres. |
\b |
Especifica que a correspondência deve terminar num limite de palavras. |
Corresponder uma ou mais vezes: +
O +
quantificador corresponde ao elemento anterior uma ou mais vezes. É equivalente a {1,}
.
+
é um quantificador ganancioso cujo equivalente preguiçoso é +?
.
Por exemplo, a expressão \ban+\w*?\b
regular tenta corresponder palavras inteiras que começam com a letra a
seguida por uma ou mais ocorrê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 falha em corresponder 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 |
Comece com um limite de palavras. |
an+ |
Corresponde a um a seguido por um ou mais n caracteres. |
\w*? |
Corresponde a um caractere de palavra zero ou mais vezes, mas o menor número possível de vezes. |
\b |
Termine com um limite de palavras. |
Concordar zero ou uma vez: ?
O ?
quantificador corresponde ao elemento anterior zero ou uma vez. É equivalente a {0,1}
.
?
é um quantificador ganancioso cujo equivalente preguiçoso é ??
.
Por exemplo, a expressão regular \ban?\b
tenta encontrar todas as palavras que começam com a letra a
seguida de zero ou uma ocorrência da letra n
. Por outras palavras, tenta fazer corresponder as 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 |
Comece com um limite de palavras. |
an? |
Corresponde a um a seguido de zero ou um n caractere. |
\b |
Termine com um limite de palavras. |
Corresponder exatamente n vezes: {n}
O {
corresponde ao elemento anterior exatamente }
vezes, onde n é qualquer inteiro.
{
n é um quantificador ganancioso cujo equivalente preguiçoso é}
{
.
Por exemplo, a expressão \b\d+\,\d{3}\b
regular 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 |
Comece com um limite de palavras. |
\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 |
Termine com um limite de palavras. |
Corresponder pelo menos n vezes: {n,}
O {
quantificador n,}
corresponde ao elemento anterior pelo menos n vezes, onde n é qualquer inteiro.
{
n é um quantificador ganancioso cujo equivalente preguiçoso é,}
{
.
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 numérico. 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 |
Comece com um limite de palavras. |
\d{2,} |
Corresponde a pelo menos dois dígitos decimais. |
\b |
Corresponde a um limite de palavras. |
\D+ |
Corresponde a pelo menos um dígito não decimal. |
Correspondência entre n e m Tempos: {n,m}
O {
quantificador n,
corresponde ao elemento precedente pelo menos }
vezes, mas não mais do que m vezes, onde n e m são inteiros.
{
n,
m}
é um quantificador ganancioso cujo equivalente preguiçoso é {
n,
m}?
.
No exemplo a seguir, a expressão (00\s){2,4}
regular tenta corresponder 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 cinco vezes, em vez do máximo de quatro. No entanto, apenas a parte inicial desta substring (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.
Match Zero ou Mais Vezes (Prezy Match): *?
O *?
quantificador corresponde ao elemento anterior zero ou mais vezes, mas o menor número de vezes possível. É a contrapartida preguiçosa do quantificador ganancioso *
.
No exemplo a seguir, a expressão \b\w*?oo\w*?\b
regular 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 |
Comece com um limite de palavras. |
\w*? |
Corresponde a zero ou mais caracteres de palavras, mas ao menor número possível de caracteres. |
oo |
Corresponde à cadeia de caracteres oo . |
\w*? |
Corresponde a zero ou mais caracteres de palavras, mas ao menor número possível de caracteres. |
\b |
Termine com um limite de palavras. |
Corresponder uma ou mais vezes (jogo preguiçoso): +?
O +?
quantificador corresponde ao elemento anterior uma ou mais vezes, mas o menor número de vezes possível. É a contrapartida preguiçosa do quantificador ganancioso +
.
Por exemplo, a expressão \b\w+?\b
regular corresponde a um ou mais caracteres separados por limites de palavras. 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.
Match Zero ou One Time (jogo preguiçoso): ??
O ??
quantificador corresponde ao elemento anterior zero ou uma vez, mas o menor número de vezes possível. É a contrapartida preguiçosa do quantificador ganancioso ?
.
Por exemplo, a expressão regular ^\s*(System.)??Console.Write(Line)??\(??
tenta corresponder às cadeias 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 precedida 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. |
Match Exactly n Times (Jogo Preguiçoso): {n}?
O {
quantificador n}?
corresponde ao elemento anterior exatamente n
vezes, onde n é qualquer inteiro. É a contrapartida preguiçosa do quantificador {
ganancioso n}
.
No exemplo a seguir, a expressão \b(\w{3,}?\.){2}?\w{3,}?\b
regular é usada para identificar um endereço de site. 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 |
Comece com um limite de palavras. |
(\w{3,}?\.) |
Corresponde a pelo menos três caracteres alfanuméricos, mas ao menor número possível de caracteres, seguido por um ponto final. Este padrão é o primeiro grupo de captura. |
(\w{3,}?\.){2}? |
Corresponde ao padrão no primeiro grupo duas vezes, mas tão poucas vezes quanto possível. |
\b |
Termine a partida com um limite de palavras. |
Match pelo menos n vezes (Lazy Match): {n,}?
O {
corresponde ao elemento anterior pelo menos ,}?
vezes, onde n
é qualquer inteiro, mas o menor número de vezes possível. É a contrapartida preguiçosa do quantificador {
ganancioso n,}
.
Veja o exemplo para o {
quantificador n}?
na seção anterior para 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.
Correspondência Entre n e m Vezes (Correspondência Preguiçosa): {n,m}?
O {
n,
m}?
quantificador corresponde ao elemento precedente entre n
e m
vezes, onde n e m são inteiros, mas o menor número de vezes possível. É a contrapartida preguiçosa do ganancioso quantificador {
n,
m.}
No exemplo a seguir, a expressão \b[A-Z](\w*?\s*?){1,10}[.!?]
regular corresponde a frases que contêm entre 1 e 10 palavras. Ele corresponde a todas as frases na cadeia de entrada, exceto 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 |
Comece com um limite de palavras. |
[A-Z] |
Corresponde a um caractere maiúsculo de A a Z. |
(\w*?\s*?) |
Corresponde a zero ou mais caracteres de palavras, seguidos por um ou mais caracteres de espaço em branco, mas o menor número de vezes possível. Este 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 ? . |
Quantifiers gananciosos e preguiçosos
Alguns quantificadores têm duas versões:
Uma versão gananciosa.
Um quantificador ganancioso tenta corresponder a um elemento o maior número de vezes possível.
Uma versão não gananciosa (ou preguiçosa).
Um quantificador não ganancioso tenta corresponder a um elemento o menor número de vezes possível. Você pode transformar um quantificador ganancioso em um quantificador preguiçoso adicionando um
?
.
Considere uma expressão regular destinada a extrair os últimos quatro dígitos de uma cadeia de números, como um número de cartão de crédito. A versão da expressão regular que usa o *
quantificador ganancioso é \b.*([0-9]{4})\b
. No entanto, se uma cadeia de caracteres contiver dois números, essa expressão regular corresponderá apenas 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 consegue corresponder ao primeiro número porque o *
quantificador tenta corresponder ao elemento anterior tantas vezes quanto possível em toda a cadeia de caracteres e, portanto, encontra sua correspondência no final da cadeia de caracteres.
Esse comportamento não é o desejado. Em vez disso, você pode usar o *?
quantificador preguiçoso 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 maior parte dos casos, expressões regulares com quantificadores gananciosos e lentos retornam as mesmas correspondências. Elas frequentemente 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 homólogos preguiçosos nunca se repetem após uma partida vazia quando o número mínimo de capturas foi encontrado. Esta regra impede que os quantificadores entrem loops infinitos em correspondências de subexpressões vazias quando o número máximo de capturas de grupo possíveis é infinito ou quase infinito.
Por exemplo, o código seguinte mostra o resultado de uma chamada para o método Regex.Match com o padrão de expressão regular (a?)*
, que corresponde a nenhum ou um caractere a
repetido zero ou mais vezes. O grupo de captura único captura cada a
e String.Empty, mas não há uma segunda correspondência vazia, pois 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 capturas e um que define um número fixo de capturas, considere os padrões (a\1|(?(1)\1)){0,2}
de expressão regular 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 |
Ou faz corresponder a com o valor do primeiro grupo capturado ... |
|(?(1) |
… ou testa se o primeiro grupo capturado foi definido. A (?(1) construção não define um grupo de captura. |
\1)) |
Se o primeiro grupo capturado existir, corresponda ao respetivo valor. Se o grupo não existir, corresponderá ao grupo String.Empty. |
A primeira expressão regular tenta corresponder a este 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\1
. O {0,2}
quantificador permite apenas correspondências vazias na última iteração. Em contraste, a segunda expressão regular corresponde a
porque avalia a\1
uma segunda vez. O número mínimo de iterações, 2, força o motor a repetir após uma partida 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.