Quantificadores gananciosos

Resumo : neste tutorial, você aprenderá como funcionam os quantificadores gananciosos e como evitar resultados inesperados usando quantificadores preguiçosos.

Quantificadores são gananciosos

Quantificadores são metacaracteres em expressões regulares que especificam a quantidade do elemento anterior. Por exemplo, o quantificador + corresponde a uma ou mais ocorrências do elemento anterior.

Por padrão, os quantificadores são gananciosos, o que significa que os quantificadores sempre tentam corresponder o máximo possível do texto de entrada, ao mesmo tempo que permitem que todo o padrão corresponda com êxito.

A razão pela qual os quantificadores são chamados de gananciosos é que eles tentam consumir o máximo possível de caracteres na string de entrada.

Vamos dar um exemplo para entender como funcionam os quantificadores gananciosos.

Suponha que você tenha uma tag de link em um fragmento HTML:

<a href="https://tutorials.acervolima.com/tutorial-c" target="_blank">Click Me</a>Linguagem de código:  HTML, XML  ( xml )

Para obter valores de atributos como "https://tutorials.acervolima.com/tutorial-c"e "_blank", você pode criar o seguinte padrão:

".+"Linguagem de código:  texto simples  ( texto simples )

Este padrão corresponde a um texto que começa com aspas ( ") seguido por um ou mais caracteres (.) e termina com aspas ( ").

using System.Text.RegularExpressions;
using static System.Console;


var html = """<a href="https://tutorials.acervolima.com/" target="blank">C# Tutorial</a>""";

var pattern = """ 
              ".+"
              """;

var matches = Regex.Matches(html, pattern);
foreach (var match in matches)
{
    WriteLine(match);
}Linguagem de código:  C#  ( cs )

Observe que usamos uma string bruta para uma string HTML e um padrão de expressão regular, que contém as aspas (“). A string bruta está disponível desde C# 11.

Saída:

"https://tutorials.acervolima.com/tutorial-c" target="blank"Linguagem de código:  texto simples  ( texto simples )

O resultado não é o que esperávamos.

O seguinte descreve como o quantificador ganancioso funciona neste exemplo:

  1. O padrão regex ".+"é aplicado à string de entrada.
  2. O primeiro caractere da string de entrada é <e .no padrão corresponde a qualquer caractere. Portanto, o mecanismo regex corresponde ao <caractere de abertura.
  3. O quantificador ganancioso +permite uma ou mais ocorrências, portanto o mecanismo regex tenta corresponder o maior número possível de caracteres.
  4. O mecanismo continua combinando todos os caracteres subsequentes até atingir o >caractere de fechamento. Isso inclui a partida "https://tutorials.acervolima.com/tutorial-c" target="blank">C# Tutorial</a>.
  5. Assim que o mecanismo atinge o >caractere de fechamento, ele percebe que o padrão ainda precisa corresponder à parte restante da string de entrada.
  6. Neste ponto, o motor aciona o retrocesso . Ele retrocede da última posição correspondida, que é o fechamento >, e passa a considerar partidas mais curtas.
  7. O mecanismo remove o último caractere >da partida e tenta combinar novamente. No entanto, ainda não encontra uma correspondência completa.
  8. O processo de retrocesso continua e o mecanismo remove os caracteres subsequentes, um por um, até encontrar uma correspondência válida.
  9. Finalmente, o mecanismo alcança uma correspondência válida com o último ” e retorna a correspondência mais longa possível: href="https://tutorials.acervolima.com/tutorial-c" target="blank".

Desligue o modo ganancioso

Para corrigir esse problema, você precisa forçar explicitamente o quantificador (+) a usar o modo não ganancioso (preguiçoso), adicionando o ponto de interrogação (?) após o quantificador + assim:

".+?"Linguagem de código:  JSON/JSON com comentários  ( json )

Por exemplo:

using System.Text.RegularExpressions;
using static System.Console;


var html = """<a href="https://tutorials.acervolima.com/" target="blank">Click Me</a>""";

var pattern = """ 
              ".+?"
              """;

var matches = Regex.Matches(html, pattern);
foreach (var match in matches)
{
    WriteLine(match);
}Linguagem de código:  C#  ( cs )

Saída:

"https://tutorials.acervolima.com/tutorial-c"
"blank"Linguagem de código:  texto simples  ( texto simples )

Agora, o programa retorna o resultado esperado.

Resumo

  • Os quantificadores são gananciosos por padrão.
  • Um quantificador ganancioso corresponde ao máximo possível da string de entrada, ao mesmo tempo que permite que o padrão geral da expressão regular corresponda com êxito.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *