Página 1 de 3

Consulta por expresión regular

NotaPublicado: 2011-06-06 11:10 @507
por teofederico
Hola, que tal, soy nuevo en el foro, estaba necesitando encontrar un grupo que trabaje con Perl, ya que hace tiempo estuve en el tema y ahora me estoy volviendo a integrar.

Mi consulta, estimo que debe ser muy simple.
Espero me puedan ayudar.

Tengo un html, donde dentro de las etiquetas <ul><il></il></ul> está la información que necesito; esto se repite dentro del código varias veces y necesito extraerlo por cada vez que encuentre la etiqueta <ul>.

Yo, en el primer momento, descargo el contenido HTML a una variable $contenido:

my $req = HTTP::Request->new(GET => $publi);
my $response = $browser->request($req);
my $contenido = $response->content();
$contenido =~ s/[\t\n]//g;

Lo limpio de tabuladores y saltos de línea.
Encuentro la región que contiene la etiqueta <ul> y la capturo a $1.

$contenido = $1;

Luego intento hacer un proceso para sustraer los datos.

while ( $contenido =~ /<ul class="gridRow.*">(.*)<div/g ) {

encuentra lo que busco, pero no lo hace por cada vez que inicia con la etiqueta <ul>. No sé si me explico bien.

Espero que alguien entienda, de lo contrario, respondo preguntas o reformulo la cuestión... Gracias.

Re: Consulta por expresión regular

NotaPublicado: 2011-06-06 14:45 @656
por ileiva
Hola teofederico. Creo que se entendería mejor si pusieras un ejemplo del código HTML que quieres procesar y lo que llevas de tu programa en Perl.

Saludos.

Re: Consulta por expresión regular

NotaPublicado: 2011-06-06 15:15 @677
por explorer
Bienvenido a los foros de Perl en español, teofederico.

Los comodines avariciosos (.*) son peligrosos, porque capturan todo lo que puedan, a veces, demás.

Deberías usar comodines no avariciosos (.*?). Algo así:

m{<ul .*?>(.*?)</ul>}

De esta manera, la captura está garantizada desde que empieza <ul> hasta el primer </ul> que encuentre.

Como dice ileiva, estaría bien ver un poco de código original.

Re: Consulta por expresión regular

NotaPublicado: 2011-06-06 19:06 @837
por teofederico
Sintáxis: [ Descargar ] [ Ocultar ]
Using html4strict Syntax Highlighting
  1. <div class="divAdsenseGridTop afsGrid ">
  2. <ul class="gridRow cat344  ">
  3.                     <li class="date"> fecha</li>
  4.                     <li class="photo"><a class='nophoto' href='#' title='#'><img/></a></li>
  5.                     <li class="title"><a href="#"> Dato </a><span class="location">#</span></li>
  6.                     <li class="category">#</li>
  7.                     <li class="price">u$s </li>
  8. </ul>
  9. <ul class="gridRow cat344  ">
  10.                     <li class="date"> fecha</li>
  11.                     <li class="photo"><a class='nophoto' href='#' title='#'><img/></a></li>
  12.                     <li class="title"><a href="#"> Dato </a><span class="location">#</span></li>
  13.                     <li class="category">#</li>
  14.                     <li class="price">u$s </li>
  15. </ul>
  16. </div>
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Esta es una porción del código; logro captar el contenido dentro de las <div>, y lo almaceno en $1

$contenido = $1;

$contenido =~ s/[\t\r]/ /g; # Elimino espacios y demás, para detectar mas fácilmente el contenido

Mi problema es al querer hacer un proceso repetitivo (while) de reconocimiento para cada <ul>, para procesar cada class (que ya lo tengo resuelto).

Disculpen, soy medio bruto explicándome.

Voy a intentar de la manera que me proponen.

Re: Consulta por expresión regular

NotaPublicado: 2011-06-06 20:08 @881
por ileiva
Bueno, asumiendo que tienes listo lo de procesar cada class, entonces algo así debería funcionar:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use File::Slurp;
  3. use strict;
  4.  
  5. my $f = read_file('file.html');
  6.  
  7. while ($f =~ /<div .*?>(.*?)<\/div>/gs ) {
  8.     my $div_content = $1;
  9.     while ($div_content =~ /<ul .*?>(.*?)<\/ul>/gs ) {
  10.         print $1;  # Procesar aquí cada class
  11.     }
  12. }
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Los modificadores g y s indican que se debe procesar todas las ocurrencias encontradas y tratar la cadena como una sola línea respectivamente.

Saludos.

Re: Consulta por expresión regular

NotaPublicado: 2011-06-06 20:17 @887
por teofederico
explorer escribiste:Bienvenido a los foros de Perl en español, teofederico.

Los comodines avariciosos (.*) son peligrosos, porque capturan todo lo que puedan, a veces, demás.

Deberías usar comodines no avariciosos (.*?). Algo así:

m{<ul .*?>(.*?)</ul>}

De esta manera, la captura está garantizada desde que empieza <ul> hasta el primer </ul> que encuentre.

Como dice ileiva, estaría bien ver un poco de código original.


Muchisimas gracias! funciono excelente!

Si estan por Argentina, les invito o unos mates o una cerveza.

Re: Consulta por expresión regular

NotaPublicado: 2011-06-06 22:55 @997
por teofederico
Efectivamente ileiva,

Ya tenía gran porción del código hecho, hasta que me di cuenta, que lo estaba haciendo mal. Ya que algunos parámetros se me escapan por hacer mal el regex, solo tuve que agregar "}g" al código de nuestro colega, para así, dejarlo funcional.

Te agradezco, ahora estoy viendo si puedo interactuar con un archivo ASP de un sitio, que no crea peticiones por url y es más complicado.

Resumiendo, el código terminó:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. if ( $contenido =~ m/(<ul class="gridRow.*">.*<\/div>)/g ) {
  2. $contenido = $1;
  3. while ( $contenido =~ m{<ul class="gridRow.*?">(.*?)</ul>}g ) { aqui parseo cada class y obtengo los datos }
  4. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¡ Gracias !

¿ Agrego al título "Resuelto" ?

Re: Consulta por expresión regular

NotaPublicado: 2011-06-07 01:29 @104
por ileiva
Qué bueno que ya lo solucionaste, para eso está el foro :).

teofederico escribiste:¿ Agrego al título "Resuelto" ?

Yo creo que sí.

Saludos.

Re: Consulta por expresión regular

NotaPublicado: 2011-06-07 01:32 @105
por teofederico
BORRADO por incumplir las normas del sitio.

Re: Consulta por expresión regular

NotaPublicado: 2011-06-07 03:49 @200
por ileiva
Basándome en una de tus respuestas anteriores, donde pusiste esto:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.     if ( $contenido =~ m/(<ul class="gridRow.*">.*<\/div>)/g ) {
  2.     $contenido = $1;
  3.     while ( $contenido =~ m{<ul class="gridRow.*?">(.*?)</ul>}g ) { aqui parseo cada class y obtengo los datos }
  4.     }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Te aconsejaría que una vez que entras al if (y luego al while) vayas creando nuevas variables para almacenar el valor de las ocurrencias en vez de modificar la misma que estás procesando, que en este caso es $contenido. Si lo piensas detenidamente, estás alterando el valor de la información que procesas por tanto pierdes lo que tenías antes de encontrar alguna ocurrencia.

Espero haya quedado claro. Saludos.