• Publicidad

Expresiones regulares más concepto greedy aplicado a ellas

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Expresiones regulares más concepto greedy aplicado a ellas

Notapor Anthares » 2009-03-29 08:13 @384

Hola :P

Lo que preguntaré seguramente es tonto pero me gusta entender bien las cosas y con Perl hace mucho había hecho una tarea para mis estudios pero pasó tanto el tiempo que ya perdí la mano....

Y esta es una de las cosas que no me acuerdo mucho :oops:

Se dice que Perl es greedy porque es "glotón": toma todo lo que puede.

Por ejemplo:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$_ = "abc11a2111111a";
print $1 if(/(.*1a$)/);
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

Esto imprime: abc11a2111111a.

Pero si tengo esto otro:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$_ = "abc11a2111111a";
print $1 if(/(1*a)/);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Imprime: a.

Esto es por que como adelante el 1 tiene * puede ser 0 o muchos unos y toma la tira vacía para el 1 y se queda con la 'a', es decir, simplemente ignora los unos.

¿No tendría que tomar todos los unos que están antes de la a? ya que al ser greedy toma todo lo que puede pero se ve que entendí mal yo algo X)

Ahora bien si pongo esto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$_ = "abc11a2111111a";
print $1 if(/(1*a)$/);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

la salida es: 111111a.

¿Por qué en este caso no hace como lo anterior?, es decir se queda con la "a" que finaliza el string y los "111111" no los toma por que toma la tira vacía.

¿Que diferencia hay entre el caso 2 y el 3? Si bien le pongo $ para indicar que tome la parte final pudiera hacer con los unos como en el ejemplo 2 y simplemente ignorarlos.

¿Y por qué con el punto se comporta 100% greedy y no así con el ejemplo 2?

En fin, perdonen tanta pregunta pero me gusta mucho estudiar Perl y sacarle provecho.

Saludos
:oops:
Anthares
Perlero nuevo
Perlero nuevo
 
Mensajes: 26
Registrado: 2007-04-30 07:18 @346

Publicidad

Notapor explorer » 2009-03-29 09:25 @434

En el primer caso,
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$_ = "abc11a2111111a";
print $1 if /(.*1a$)/;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
le estás dando una pista a las expresiones regulares para que miren la búsqueda del patrón hacia el final de cadena. Y el comodín glotón acapara todo (.*) lo que antecede a un 1a final ($).

En el segundo caso,
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$_ = "abc11a2111111a";
print $1 if /(1*a)/;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
no estás diciendo dónde tiene que mirar, así que el motor de expresiones regulares empieza a mirar por la parte izquierda y se dirige hacia la derecha. Como la primera a que está al principio (a la izquierda, repito) hace coincidir el patrón que le pides (0 veces 1 más una a) entonces termina con éxito.

En el tercer caso,
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$_ = "abc11a2111111a";
print $1 if(/(1*a)$/);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
vuelves a indicar por dónde tiene que mirar: por el final. Y le estás pidiendo que capture todos los posibles 1 que antecedan a una a final ($).

Anthares escribiste:¿Por qué en este caso no hace como lo anterior?, es decir se queda con la "a" que finaliza el string y los "111111" no los toma por que toma la tira vacía.

¿Que diferencia hay entre el caso 2 y el 3? Si bien le pongo $ para indicar que tome la parte final pudiera hacer con los unos como en el ejemplo 2 y simplemente ignorarlos.
El operador glotón intenta siempre quedarse con la mayor cantidad, y en ese caso hay un montón de 1 que anteceden a la a final ($). Mientras, en el segundo caso, como no estás diciendo qué a tiene que mirar, lo hace desde la parte izquierda, y allí encuentra algo que coincide con el patrón de búsqueda, por lo que solo muestra la a (no le precede ningún 1).

Vamos, que se tratan de dos diferentes 'a'. Una está al final y otra al principio. Y siempre devuelve el primer patrón que encuentre, no el más grande.

Anthares escribiste:¿Y por qué con el punto se comporta 100% greedy y no así con el ejemplo 2?

El punto equivale a cualquier carácter, así que el patrón de búsqueda (.*) quiere decir que capture todo lo posible. Por eso es peligroso porque en muchas ocasiones capturará más de lo normal.

Esa es la razón por la que existen los operadores no glotones: (.+?) que hacen justo lo contrario: se quedan con la parte más pequeña que encuentren.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor Anthares » 2009-03-29 09:35 @441

Muchas, muchas gracias, excelente explicación :D

La verdad que la primera a de abc me la comí yo ¡Qué vergüenza! Jejeje, gracias por la excelente explicación, me quedó claro este tema.

Saludos
Anthares
Perlero nuevo
Perlero nuevo
 
Mensajes: 26
Registrado: 2007-04-30 07:18 @346


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 6 invitados

cron