En Perl, los cuantificadores en expresiones regulares — *, +, ?, {n,m} — son, por defecto, codiciosos (greedy): capturan la mayor cantidad posible de caracteres que coinciden con el patrón.
Agregar ? después del cuantificador lo convierte en perezoso (lazy o non-greedy): captura la menor cantidad posible de caracteres para que toda la expresión regular coincida.
my $str = 'foo <bar> baz <quux>'; $str =~ /<.*>/; # Capturará '<bar> baz <quux>'
my $str = 'foo <bar> baz <quux>'; $str =~ /<.*?>/; # Capturará '<bar>'
¡Una expresión codiciosa puede "comer" más de lo que esperas al analizar HTML y otras construcciones anidadas!
¿En qué se diferencian las siguientes dos expresiones regulares al analizar la cadena
<a><b><c>:/<(.*)>/y/<(.*?)>/?
Respuesta:
/<(.*)>/ (codiciosa) capturará el bloque máximo — coincidencia: <a><b><c>/<(.*?)>/ (perezosa) — solo el primer grupo: <a>Ejemplo:
my $s = '<a><b><c>'; $s =~ /<(.*)>/; # $1: 'a><b><c' $s =~ /<(.*?)>/; # $1: 'a'
Historia
En una aplicación para importar titulares de noticias, un programador quería analizar el nombre de la etiqueta en la cadena
<title>Noticia</title>, utilizando/\<(.*)\>/. Como resultado, la expresión regular capturó toda la cadena entre<el primero y>el último, en lugar del elemento deseado. El error se encontró cuando aparecieron etiquetas anidadas.
Historia
En un analizador lógico para resaltar cadenas entre comillas, la plantilla utilizada
/"(.*)"/inesperadamente capturó todo entre la primera y la última comilla. Como resultado, el marcado se rompió incorrectamente, hasta que se reemplazó la plantilla por/"(.*?)"/.
Historia
En un analizador automático de CSV con posibilidad de comillas, se escribió incorrectamente la plantilla con "codicia", lo que causó que varias columnas se combinaran en una. El fallo del analizador introducido se identificó solo en grandes datos — la modificación perezosa de la plantilla resolvió el problema.