• Publicidad

Haciendo una nube de etiquetas

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

Haciendo una nube de etiquetas

Notapor ragnar131 » 2008-04-03 13:38 @610

Buenas.
Lo primero, presentarme. Soy Aitor, un estudiante de Informática que por una asignatura he comenzado a estudiar Perl.

Mis conocimientos son mínimos y las dudas aparecen rápidamente.

Tras mucho buscar y no encontrar lo que buscaba, he decidido probar suerte en este foro.

Veréis, tengo que conseguir hacer en Perl, una nube de etiquetas, con las etiquetas que se cogen de un fichero xhtml, concretamente, el de menéame:

http://meneame.net/rss2.php

(no busco hacer publicidad, es para mostrar el esquema del fichero).

Desde este fichero, tengo que obtener los valores de etiquetas, es decir que cada noticia tiene unas etiquetas asociadas (debajo de cada noticia hay una línea escrita como "etiquetas: ".

Pues yo tengo que hacerme con esos valores, para después ordenarlos, medir su frecuencia y finalmente hacer un fichero html relacionando a cada etiqueta un tamaño de fuente en función de la frecuencia de apariciones. Una nube de tags al fin y al cabo.

Bueno, el caso es que con este código:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
`more feed.xhtml | tr -s "</STRONG>" '\012' | tr -s "</P>" '\012' >archivo1`;
 @texto = `cat archivo1`;
 open F, ">fin";
 foreach (@texto) {
        $_ =~/^'\s:'/;

        if($_=~/^:\s\w/ ){#: espacio y alfanumérico. Así tengo las etiquetas.
 
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

obtengo una serie de líneas de este estilo:
": etiqueta1,etiqueta2..." donde etiquetaX puede estar compuesta de varias palabras separadas con espacios o contener el caracter '%' por ejemplo.

Mi intención es quitar ':' y el espacio que le sigue, pero me es imposible.

He probado con s/, con tr/ y sus opciones, he probado de todo, y no lo he conseguido:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
`more feed.xhtml | tr -s "</STRONG>" '\012' | tr -s "</P>" '\012' >archivo1`;
 @texto = `cat archivo1`;
 open F, ">fin";
 foreach (@texto) {
        $_ =~/^'\s:'/;

        if($_=~/^:\s\w/ ){#: espacio y alfanumérico. Así tengo las etiquetas.
                $_=~ tr/^:/ /;#Quito los : al inicio.
                #$_=~ tr/^ / /; #Quitar el espacio del inicio??
                #$_=~ tr-c-d /'\W'/'\b'/
                #$_=~ tr -cd "[:blank:]" $_
                #$_=~ tr -d /'\b'/ $_
                #$_=~ tr/,/\n/;
                $_=~ tr-d/[\s\s\w*]//

                #$_=~ tr/^\s / /;#Quito el espacio del inicio.
                #print "$_\n";
                print F "$_";

        }#if
        #`more etiquetas`;
}#for
close F;
 
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

¿Sabríais explicarme lo que hago mal y qué debo hacer para obtener la líneas de palabras tal cuál?

Gracias por vuestro tiempo y atención.
Recibid un cordial saludo, Aitor.
ragnar131
Perlero nuevo
Perlero nuevo
 
Mensajes: 8
Registrado: 2008-04-03 13:23 @599

Publicidad

Notapor explorer » 2008-04-03 19:01 @834

Bienvenido a los foros de Perl en Español, Aitor.

Primero, deseamos que el estudio de Perl sea por diversión, interés y ganas de aprender, aparte de la obligación.

Un primer detalle: El lenguaje se llama "Perl". No "PERL" (no son siglas, como el PHP). Ni tampoco "perl", pues así, en minúsculas, es como nos referimos al propio ejecutable intérprete de Perl. Más información, en la página Perl de la Wikipedia.

Segundo, la tarea que tienes que hacer es de las típicas que se resuelven muy bien con Perl. Como es natural, al principio, cuando estamos aprendiendo un lenguaje, intentamos resolverlo de las formas y técnicas que conocemos de lenguajes anteriores.

En tu primer código se vé que estás usando una llamada a unos comandos externos con una serie de tuberías, para dejar el resultado en un fichero temporal. Bueno, pues has de saber que no es necesario hacer nada de eso. Pero para empezar, vale ("Si funciona, no lo toques").

En ese código estás haciendo el truco de poner retornos de carro en los lugares interesantes de las líneas con "etiquetas", para luego procesarlas con el bucle while.

De momento te has atascado con el tema de quitar el inicial ':'. Como primer comentario, decirte que dentro de tr// NO hay expresiones regulares, sino cadenas de caracteres. tr// es una 'transliteralización' de unos caracteres en otros. Pero ese cambio no se define con expresiones regulares.

La solución (algunas de las muchas) son:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
for ( @texto ) {
    if ( /^:/ ) {
        s/^://; # o también tr/://d
    }
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Observa: con s/^:// estamos indicando que queremos sustituir el carácter ':' que hay al principio de una línea (^) por... nada. Con tr/://, lo que hacemos es borrar (/d) todos los caracteres ':' de la cadena. (Suponiendo que las marcas no deben tener ':', entonces los dos funcionarán igual.

Naturalmente, hay otras formas de resolverlo, que, si quieres, comentaremos aquí.
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 ragnar131 » 2008-04-04 14:08 @630

Antes de nada, gracias.
Como bien decís, el conocimiento de Perl es en parte por una obligación, lo cuál no resta el interés que crece en mí al no haberme introducido nunca en el mundo del scripting.
Respecto al nombre del lenguaje, tomo nota. Procuraré no equivocarme en ello por lo menos.
Entrando en el trabajo, sí; he intentado utilizar trucos para preparar el texto de manera que pueda terminar seleccionando únicamente las líneas que me interesan.
Si como decís hay otras soluciones, no me importaría conocerlas por culturilla, aunque como ya funciona, seguiré con esta forma.
Lo que no sabía es que la opción delete de tr va al final con un /d. Ahora he podido sacar un fichero de texto, con todas las etiquetas bien formateadas y la cuenta de las apariciones de cada una de ellas en el fichero inicial.

Dejo el hilo abierto a cualquier tipo de técnica para filtrar texto, que seguro que viene bien para alguna otra ocasión o situación más complicada.
Pues seguiré con ello. A ver qué tal se me da la escritura en el fichero HTML. Gracias por la respuesta.
Un saludo, Aitor.
ragnar131
Perlero nuevo
Perlero nuevo
 
Mensajes: 8
Registrado: 2008-04-03 13:23 @599

Notapor ragnar131 » 2008-04-05 11:38 @526

Hola de nuevo.
Tras haber conseguido realizar la nube de tags, estoy intentando hacer lo mismo, pero con la lista de palabras obtenidas de cada noticia del fichero.
Lo que intento es seleccionar sólo aquellas etiquetas que cumplan con un formato determinado:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$_ =~ m/<h3><a href="http:.*">/;

 
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Pero no me hace ni caso. Seguramente no he comprendido bien el funcionamiento de m (match, ¿no?), pero lo que buscaba era, que seleccionase el texto que cumpliese con ese formato. En esta ocasión, pese al uso de *, no utilizo expresión regular, sólo quiero reconocer un pedazo de texto concreto y sacarlo posteriormente a otro fichero.

Como algo estaré haciendo mal, ¿sabríais explicarme el qué? O indicarme la manera más correcta (volviendo al hilo de maneras adecuadas de filtrar texto), o sino también, documentación interesante sobre el tema si la conocéis (yo por ahora no he dado con algo que me aclarase mucho).

Una vez más, gracias por vuestro tiempo y atención.
Recibid un cordial saludo, Aitor.
ragnar131
Perlero nuevo
Perlero nuevo
 
Mensajes: 8
Registrado: 2008-04-03 13:23 @599

Notapor explorer » 2008-04-05 12:08 @547

Tienes que usar los paréntesis de captura...
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
m/<h3><a href="http:(.*?)">/;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Con .*? nos quedamos con todos los caracteres que hay entre dos caracteres de comillas dobles. Si hubiéramos puesto .* capturará todos los caracteres de la línea, sean cuales sean, hasta el último carácter '"' de la línea. Hay una ligera diferencia.

Más información en la documentación de perlre y el tutorial oficial o alguno de los tutoriales que hay en Español, en este sitio web o el resto de Internet. Y aquí mismo, desde luego.
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 explorer » 2008-04-05 19:33 @856

Aquí hay otra forma de contar la frecuencia de las etiquetas:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
use warnings;
use strict;

# Dos formas de obtener la página rss:
# Directamente por Internet
use LWP::Simple;
my $rss = get('http://meneame.net/rss2.php');

# O a través de un fichero
#my $rss = do { local $/; open F,"rss.txt"; <F> };

# Contar las etiquetas
my %tags;
while ( $rss =~ /etiquetas.*?: (.*?)</g ) {
    my @tags = split ", ", $1;
    foreach my $tag ( @tags ) {
        $tags{ $tag }++;
    }
}

# Y sacamos las frecuencias
foreach my $tag ( sort keys %tags ) {
    print $tags{ $tag },"\t", $tag, "\n";
}

__END__
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
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 ragnar131 » 2008-04-05 19:44 @864

Muchas gracias por la ayuda.
La segunda versión escapa todavía a mi conocimiento, pero la estudiaré. Más que nada por lo que puede aportar, veo que se importan librerías y se utilizan funciones que desconozco.
Una vez más gracias.
Recibid un cordial saludo, Aitor.
ragnar131
Perlero nuevo
Perlero nuevo
 
Mensajes: 8
Registrado: 2008-04-03 13:23 @599


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado