Regex ganancioso

Resumo : neste tutorial, você aprenderá sobre o modo guloso de regex e como ele afeta a maneira como os quantificadores procuram correspondências.

O problema com o modo ganancioso de regex

Suponha que você tenha a seguinte string:

<a href="/" title="Go to homepage">Home</a>Linguagem de código:  PHP  ( php )

E você deseja combinar o texto entre aspas ( ""). Para fazer isso, você pode usar o seguinte padrão que inclui a classe de caracteres. ponto ( ) e o quantificador ( ) :+

".+"Linguagem de código:  PHP  ( php )

O significado do padrão é o seguinte:

  • "começa com uma citação
  • .corresponde a qualquer caractere, exceto a nova linha
  • +corresponde ao caractere uma ou mais vezes
  • "termina com a citação

O seguinte usa a preg_match_all()função para encontrar uma correspondência na string com o padrão:

<?php

$str = '<a href="/" title="Go to the homepage">Home</a>';
$pattern = '/".+"/';

if (preg_match_all($pattern, $str, $matches)) {
    print_r($matches);
}Linguagem de código:  PHP  ( php )

Ele retorna o seguinte:

Array
(
    [0] => "/" title="Go to the homepage"
)Linguagem de código:  PHP  ( php )

Este resultado não é o que você esperava.

A razão é que o quantificador ( +) usa o modo ganancioso por padrão. No modo guloso, o quantificador ( +) tenta corresponder ao seu elemento anterior (um caractere) tantas vezes quanto possível.

Vamos entender como funciona o modo guloso de regex.

Entenda como funciona o modo guloso de regex

Para combinar o $strcom o $pattern, o mecanismo regex corresponderá a todas as posições no $strcomeçando $patternna primeira posição da string.

Portanto, o mecanismo regex inicia a partir do primeiro caractere do arquivo $str. Como é o <que não corresponde à aspa ( ") no padrão, o mecanismo regex continua a pesquisar até atingir a primeira aspa ( ") na string:

regex ganancioso - comece a combinar

O mecanismo regex analisa o padrão e combina a string com a próxima regra .+. Como a .+regra corresponde a um caractere uma ou mais vezes, o mecanismo regex corresponde a todos os caracteres até chegar ao final da string:

regex ganancioso

O mecanismo regex examina a última regra do padrão, que é uma aspa (“).

Porém, já chega ao final da string. Não há mais personagem para combinar. Foi muito ganancioso para ir longe demais.

Portanto, o mecanismo regex volta do final da string para encontrar a aspa (“). Isso é chamado de retrocesso:

regex retrocesso ganancioso

Como resultado, a correspondência é a seguinte substring que não é o que você esperava:

regex ganancioso
"/" title="Go to homepage"Linguagem de código:  PHP  ( php )

Por padrão, outros quantificadores também usam o modo ganancioso. Para corrigir esse problema, você precisa transformar o modo ganancioso em um modo não ganancioso (ou preguiçoso), adicionando um ponto de interrogação ( ?) ao quantificador como este:

".+?"Linguagem de código:  PHP  ( php )

O código a seguir retorna o resultado esperado:

<?php

$str = '<a href="/" title="Go to the homepage">Home</a>';
$pattern = '/".+?"/';

if (preg_match_all($pattern, $str, $matches)) {
    print_r($matches[0]);
}Linguagem de código:  PHP  ( php )

Saída:

Array
(
    [0] => "/"
    [1] => "Go to the homepage"
)Linguagem de código:  PHP  ( php )

Para entender como funciona o modo regex não-ganancioso , confira o tutorial regex não-ganancioso .

Resumo

  • Por padrão, os quantificadores usam o modo ganancioso.
  • Um quantificador ganancioso tenta corresponder ao seu elemento anterior tantas vezes quanto possível.

Deixe um comentário

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