Perl en Español

  1. Home
  2. Tutoriales
  3. Foro
  4. Artículos
  5. Donativos
  6. Publicidad
 

Reconocer patron con constantes y sec. de escape

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Básico
Mensaje Lun Abr 03, 2006 11:26 am
bartoldo
Perlero Nuevo
Perlero Nuevo
Registrado: 01 Abr 2006
Mensajes: 7
Reconocer patron con constantes y sec. de escape Responder citando

pues bien, tengo otro problema, no he encontrado algun tutorial que tenga ejemplos más sustanciosos. Es decir, cuando quiero reconocer strings del tipo Proceso cualquier cosa nombre{nom1}, uso el siguiente código
Código:

if /Proceso(\.*)nombre:{(\s*\w+\s*)}/
   print $2; //imprimiría el nombre del proceso

Pues bien, la mezcla entre secuencias de escape(\.*,etc), y strings 'constantes' no se como llamarle (nombre, Proceso,{,}), me causa problemas cuando las tengo mezcladas como en este ejemplo, y no me reconoce el patrón.
gracias, saludos
Mensaje Lun Abr 03, 2006 11:48 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4129
Ubicación: Valladolid, España
Re: Reconocer patron con constantes y sec. de escape Responder citando

bartoldo escribió:
pues bien, tengo otro problema, no he encontrado algun tutorial que tenga ejemplos más sustanciosos.
En este web hay un par de ellos: http://perlenespanol.baboonsoftware.com/archives-tut/cat_expresiones_regulares.html
bartoldo escribió:
Es decir, cuando quiero reconocer strings del tipo Proceso cualquier cosa nombre{nom1}, uso el siguiente código
Código:
if /Proceso(\.*)nombre:{(\s*\w+\s*)}/
   print $2; //imprimiría el nombre del proceso

Pues bien, la mezcla entre secuencias de escape(\.*,etc), y strings 'constantes' no se como llamarle (nombre, Proceso,{,}), me causa problemas cuando las tengo mezcladas como en este ejemplo, y no me reconoce el patrón.
Primero, \.* no es "cualquier cosa", sino que es "0 o más puntos". "Cualquier cosa" es .*. A veces se nos escapa lo que hay que escapar (o no :) )
En cuanto al patrón que buscas, entiendo que sería
Código:
if ( /Proceso.+nombre:\{(\s*\w+\s*)\}/ ) {
    print "Proceso: $1\n";
}
que según veo, entre los corchetes, lo que buscas es una única palabra rodeada posiblemente por espacios en blanco.

En muchas ocasiones, la mejor forma de construir una expresión regular es yendo poco a poco y utilizando la línea de comandos, ya que perl lo podemos ejecutar desde ella.
Si tengo que reconocer un patrón complicado como por ejemplo (0(9|8)_|new_*)?price(2|_new|_0(8|9))?\.zip, primero intentaría hacerlo paso a paso, por cada par de paréntesis de captura.
(Ese patrón reconoce nombres de ficheros zip infectados con el virus Bagle.bg).
Mensaje Lun Abr 03, 2006 12:44 pm
bartoldo
Perlero Nuevo
Perlero Nuevo
Registrado: 01 Abr 2006
Mensajes: 7
Responder citando

gracias, siempre dando una mano.
Si, no era cualquier cosa, quise decir que fuera cualquier carácter y sin querer puse el "\". Efectivamente estoy armando las expresiones de a poco, pero llego a un punto que no veo salida.

El tutorial lo estuve leyendo, pero no vi algo referente a la sustitución de cadenas como necesito. Sino algo mas bien descriptivo.
Por ejemplo si pongo algo del tipo $var = "\w*" me genera problemas
si lo pongo '\w*' funciona como una 'macro'. Sin embargo, el contenido de otras variables si puedo ponerlo entre " ", son detalles, pero para quienes comenzamos no están en ningun tutorial, sino en la experiencia por las macanas.

Ahora por ejemplo tengo que buscar algo del tipo \cite{ cita cualquiera}
y hay solo una que no me la reconoce, si el resto de las 'cite'.
Unica restriccion, lo que va entre {} está en minúscula.

Código:
$er_label = '(\s*[a-z]\w*\s*)((,\s*[a-z]\w*\s*|)*)'; if /\\label\{$er_label\}/g;


Por otra parte debo reconocer cosas del tipo (ocupa varias líneas)
\begin{figure}
............
label\{nombreFigura}
.................
\end{figure} y sustituirlo.
Código:

s/\\begin\{figure\}.*\\label\{(\s*\w+\s*)\}\\end\{figure\}/Figura: $1/gsm;
no me está funcionando, ni esto:
Código:

s/\\begin\{figure\}(\s*\w+\s*)\\end\{figure\}/Figura: $1/gsm;


sigo viendo, gracias
Mensaje Lun Abr 03, 2006 1:20 pm
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4129
Ubicación: Valladolid, España
Responder citando

bartoldo escribió:
El tutorial lo estuve leyendo, pero no vi algo referente a la sustitución de cadenas como necesito. Sino algo mas bien descriptivo.
Por ejemplo si pongo algo del tipo $var = "\w*" me genera problemas
si lo pongo '\w*' funciona como una 'macro'.
Sin embargo, el contenido de otras variables si puedo ponerlo entre " ", son detalles, pero para quienes comenzamos no están en ningun tutorial, sino en la experiencia por las macanas.
Lo he entendido. Lo que quieres es meter expresiones regulares en variables. Una forma de hacerlo es con el operador qr
Código:
$patron = qr{(\s*[a-z]\w*\s*)((,\s*[a-z]\w*\s*|)*)};
if ( $linea =~ /$patron/ )  { ... }
pero tal como lo haces también es válido.
bartoldo escribió:
Ahora por ejemplo tengo que buscar algo del tipo \cite{ cita cualquiera}
y hay solo una que no me la reconoce, si el resto de las 'cite'.
Unica restriccion, lo que va entre {} está en minúscula.
Código:
$er_label = '(\s*[a-z]\w*\s*)((,\s*[a-z]\w*\s*|)*)'; if /\\label\{$er_label\}/g;
Si lo que va entre corchetes no tiene corchetes, se podría seleccionar la cita de esa manera:
Código:
$linea =~ /\\cite\{(.+?)\}/;
print $1;
bartoldo escribió:
Por otra parte debo reconocer cosas del tipo
\begin{figure}
............
label\{nombreFigura}
.................
\end{figure} y sustituirlo.
Anda!. ¡Si parece rtf! ¿O es Latex?
bartoldo escribió:
Código:
s/\\begin\{figure\}.*\\label\{(\s*\w+\s*)\}\\end\{figure\}/Figura: $1/gsm;
no me está funcionando, ni esto:
Código:

s/\\begin\{figure\}(\s*\w+\s*)\\end\{figure\}/Figura: $1/gsm;
Supongamos que el fichero kk.rtf sea
Código:
\begin{figure}
............
\label{   nombreFigura1}
.................
\end{figure}

\begin{figure}
............
\label{nombreFigura3    }
.................
\end{figure}

\begin{figure}
............
\label{   nombreFigura2   }
.................
\end{figure}
Luego tenemos el programa Perl
Código:
#!/usr/bin/perl
open FILE, "<kk.rtf";
while ( <FILE> ) {          # Leemos todo el fichero a una variable
  $fichero = $fichero . $_;
}
close FILE;
$fichero =~ s/\\begin\{figure\}.*?\\label\{\s*(\w+)\s*\}.*?\\end\{figure\}/Figura: $1/gsm; # Transmutación!
print $fichero;
Entonces la salida es
Código:
Figura: nombreFigura1

Figura: nombreFigura3

Figura: nombreFigura2
Explicación: El conjunto '.*' es algo 'peligroso' porque significa 'cualquier secuencia de caracteres' y 'cualquiera' es eso: por defecto, el '*' se 'come' TODOS los caracteres que pueda encontrar. Si no pusieramos el '?', el '.*' que hay detrás del primer \begin reconocería todos los caracteres hasta el ÚLTIMO \label del fichero.
Mientras que con el '*' le decimos que coja TODOS los posibles, con el '*?' le decimos que coja los MENOS POSIBLES, porque no queremos que vaya 'más allá' de lo razonable.

A tu expresión regular le faltaba un '.*' y poner los '?' para evitar la glotonería. Además, fíjate que he sacado los '\s*' fuera de la captura, para aprovechar y quitar los espacios en blanco de las etiquetas.
Mensaje Lun Abr 03, 2006 2:38 pm
bartoldo
Perlero Nuevo
Perlero Nuevo
Registrado: 01 Abr 2006
Mensajes: 7
Responder citando

Exacto, es un analizador sintáctico para un texto en Latex.

Bueno, pude reconocer las figuras, solo me falta ahora, capturar una de las citas. Tampoco con esta er me pasa /\\cite\{(.+?)\}/ , pero la acomodé a que fuera /\\cite{\s*[a-z](.+?\}/ porque deben comenzar con minúsculas.
La única cosa a distinguir es que dice 'cite{algo}.' (fin de línea) Pero no es la unica 'cite' previo a un . y \n. No se porqué a esa en particular no la reconoce.

Genial el ?, me di cuenta tal como estaba me tragaba mas strings que los que necesitaba, estaba viendo como frenar eso.

te agradezco las aclaraciones, saludos
Publicar nuevo tema   Responder al tema    Foros de discusión -> Básico Todas las horas son GMT - 6 Horas
Página 1 de 1



Powered by phpBB © 2001, 2005 phpBB Group