• Publicidad

Filtrar palabras en un archivo de texto

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

Filtrar palabras en un archivo de texto

Notapor guillermelc » 2007-11-16 08:17 @387

Hola a todos.

Me han mandado una práctica que consiste en lo siguiente:
  • Tengo un primer archivo con palabras que debo eliminar. Ejemplo: desde, con, un, una, luego, entonces, para, así, etcétera.
  • Tengo un segundo archivo en el cual debo eliminar todas las palabras anteriores. Ejemplo: "con dinero compro una casa" ---> "dinero compro casa"
Yo estoy haciendo dos bucles while, uno que lea cada palabra a eliminar y en el segundo, por cada frase del fichero, que me sustituya la palabra a eliminar leída anteriormente, por un "blanco" o la elimine... por cierto... ¿eso cómo se hace?

¿Creéis que voy por buen camino? ¿Alguna sugerencia?

El código que he escrito no me sustituye cada palabra por un "blanco" o la elimina, sino que al final de la frase me escribe el "blanco", el retorno de carro, o lo que yo quiera...

¡Muchas gracias de nuevo y perdonad por las molestias!

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
open (F,'texto_prueba.txt');
open (F2,'palabras_a_segmentar.txt');
open (F3,'>pruebasalidatp3.txt');

        while( $linea_segmentar =<F2>){
        #en $linea voy a tener la primera linea del texto,luego la 2,la 3...
        #es lo primero que debo leer para saber si esta contenida en el texto de prueba
                while( $linea_texto =<F>){
                       
                        $linea_texto =~ s/[$linea_segmentar]/\n/g;
                        print F3 $linea_texto if $linea_texto;
                }      
        }

close (F);
close (F2);
close (F3);
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
guillermelc
Perlero nuevo
Perlero nuevo
 
Mensajes: 7
Registrado: 2007-11-13 12:33 @565

Publicidad

Notapor explorer » 2007-11-16 08:41 @403

Puedes hacerlo exactamente como lo has dicho, pero es mejor cambiar un poco el primer paso:[listcz][*cz]Lee todo el fichero de las palabras a excluir y las metes en un array[/*:mcz]
[*cz]Haces un bucle por todas las líneas del fichero a filtrar[/*:mcz]
[*cz]Por cada línea, haces un bucle por las palabras a buscar[/*:mcz]
[*cz]Por cada palabra, la metes en una expresión regular. En ella, el procedimiento de "borrar" es sencillamente, dejando vacío la parte de reemplazo, en el operador de sustitución.[/*:mcz][/list:ucz]Otra forma sería crear una expresión regular con todas las palabras a excluir, y pasarla por cada línea del fichero. De esto hay algunos ejemplos en este foro.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Filtrar palabras en un archivo de texto

Notapor Jenda » 2007-11-17 09:32 @439

guillermelc escribiste:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
...
                        $linea_texto =~ s/[$linea_segmentar]/\n/g;
...
 
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¡Lea algo sobre expresiones regulares! [] significa "uno de estos símbolos". Así que s/[algo]/\n/g no significa "busca 'algo' y sustitúyelo por nueva línea" sino "busca y sustituye cada 'a' o 'g' o 'l' o 'o' ".
Si $linea_segmentar debe ser la palabra que quieres buscar debes usar:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$linea_texto =~ s/\b$linea_segmentar\b/\n/g;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

(\b significa el comienzo o fin de una palabra) porque no quieres buscar las letras dentro de palabras, no quieres encontrar 'con' en 'Encontrar dinero'.

Hay dos problemas más en tu código. De primero, el $linea_segmentar contiene el \n, debes eliminarlo con chomp().

De segundo, lees todo el contento de 'texto_prueba.txt' después de leer la primera palabra del 'palabras_a_segmentar.txt' y luego no hay nada para leer cuando buscas la segunda.
Jenda
Perlero nuevo
Perlero nuevo
 
Mensajes: 132
Registrado: 2007-10-29 06:31 @313
Ubicación: Praga, Republica Checa

Notapor guillermelc » 2007-11-27 18:03 @794

Hola chicos/as.

Siento no haber contestado desde hace dos semanas pero en que trabajo por el día y estudio por las noches estoy que me va a dar algo...:(

Sigo con mi problema de borrar todas las palabras que me dan en un primer fichero. Éste tiene la siguiente estructura:

Código: Seleccionar todo
#################################################
# Palabras funcionales que debo borrar    A   #
#################################################
a
andar
arriba
abajo
#################################     
#        B                        #     
#################################
bien
bueno
bastante


Debería recoger en un array todas las palabras, luego recorrer las líneas del segundo fichero, comprobar que en una línea esté la palabra de mi array y borrarla ¿ok?

He estado visitando el foro y he visto un ejemplo para quedarme con las diferentes palabras de una cadena--> "personajes Disney".

Pues bien, cuando transcribo este código al mío, hago un print de mi array y me devuelve datos muy raros.

A ver si me podéis echar una mano.

Muchísimas gracias como siempre, por vuestra amabilidad.

Como podéis observar estoy volviendo a empezar...pasito a pasito

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
open (F,'texto_prueba.txt');
open (F2,'palabras_a_segmentar.txt');
open (F3,'>pruebasalidatp3.txt');

                while($linea_segmentar = <F2>){  # my $personajes = "Mickey Pluto Donald Bambi Dumbo";

                my @palabras = split(/\s+/, $linea_segmentar); #my @personajes = split(/\s+/, $personajes);
                print $palabras[1];

        }
close (F);
close (F2);
close (F3);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Cuando hago el print me sale por pantalla muchísimos datos y nada de "andar" "bien" etc que es lo que yo quería... :?

¡¡¡Gracias de nuevo!!!
guillermelc
Perlero nuevo
Perlero nuevo
 
Mensajes: 7
Registrado: 2007-11-13 12:33 @565

Notapor guillermelc » 2007-12-01 05:23 @266

Hola chicos, llevo toda la mañana con la maldita práctica y ya me estoy empezando a desesperar...

He hecho varios intentos y sin éxito alguno...
Me he dicho bueno empiezo OTRA VEZ DE 0 y voy haciendo "prints" para ver lo que saca:
Me encuentro con la sorpresa siguiente:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
open F,'texto_prueba.txt' or die "Error abrir datos.dat: $!\n";
open F2,'palabras_a_segmentar.txt' or die "Error abrir datos.dat: $!\n";
open F3,'>pruebasalidatp3.txt' or die "Error abrir datos.dat: $!\n";

                  while( $lineaseg =<F2>){
                        printf chomp($lineaseg);  
                        #en $linea voy a tener la primera linea del texto,luego la 2,la 3...
                        #es lo primero que debo leer para saber si esta contenida en el texto de prueba
                        while( $lineatext =<F>){    
                                printf chomp($lineaseg);                
                                $linea_texto =~ s/\b$linea_segmentar\b/\n/g;
                                print F3 $linea_texto if $linea_texto;
                       
        }
        }
close (F);
close (F2);
close (F3);
 
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Cuando imprimo línea a segmentar por pantalla me devuelve cadenas de 100001111111111111111111111111111111111111111111111111
¿Es que no me compila bien? ¿Me estoy volviendo loco? Es el Ubuntu... ya no sé que pensar.

Gracias de nuevo
guillermelc
Perlero nuevo
Perlero nuevo
 
Mensajes: 7
Registrado: 2007-11-13 12:33 @565

Notapor explorer » 2007-12-01 06:14 @301

Los unos y ceros salen del printf chomp....

Sería mejor:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
while ( $lineatext = <F> ) {
    print $lineatext;
    $lineatext =~ s/\b$lineaseg\b//g;
    print F3 $lineatext;
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Es decir:
* quitamos el chomp porque no nos hace falta (queremos mantener los finales de línea también en la salida)
* Hacemos la sustitución de la palabra a quitar, por nada, para toda la línea
* Sacamos el resultado

De todas formas, estás haciendo doble bucle: deberías abrir y cerrar el fichero con las líneas a filtrar por CADA palabra de 'palabras_a_segmentar.txt'.
Última edición por explorer el 2007-12-01 06:35 @316, editado 1 vez en total
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor explorer » 2007-12-01 06:33 @314

Hay un problema que veo a la hora de leer el fichero con las palabras que hay que borrar: no tienes en cuenta que no hay que tener en cuenta (:P) a las palabras que están dentro de los comentarios.

De hecho, hay que filtrar los comentarios.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my @palabras_a_borrar;
open PALABRAS, '<palabras_a_segmentar.txt';
while ( <PALABRAS> ) {
    next if /#/;    # Si la línea tiene esto, no nos interesa

    chomp;
    push @palabras_a_borrar, $_;   # Suponemos que hay una sola palabra por línea
}
close PALABRAS;
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: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor guillermelc » 2007-12-01 08:41 @403

Hola Explorer,
Muchas a gracias por las respuesta.
Pongo el código que he hecho y que "en teoría" debería funcionar, eso sí, no me cambia ninguna palabra por blanco -misterios de la vida-

Digo esto porque tanto tú, como Jenda y yo(viendo manuales) con este código:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$lineatext =~ s/\b$lineaseg\b//g;
 
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Me debería cambiar la palabra por blancos.

Sobre lo de los dos bucles while, hace lo que quiero correctamente:
Primero cojo la primera palabra a eliminar, y después recorro el segundo fichero donde debo eliminar las concordancias con la palabra leída en el primer while.

Dejo el código para que a alguien le sirva de ayuda y gracias de nuevo:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
open F2,'palabras_a_segmentar.txt' or die "Error abrir datos.dat: $!\n";
open F3,'>pruebasalidatp33.txt' or die "Error abrir datos.dat: $!\n";

                  while($lineaseg =<F2>){
                        #en $lineaseg voy a tenerer la 1ª palabra a borrar la 2ª,3ª etc
                                open F,'texto_prueba.txt' or die "Error abrir datos.dat: $!\n";
                                while($lineatext =<F>){                        
                                $lineatext =~ s/\b$lineaseg\b/\n/g; #en lineatext tengo toda la frase
                                #print $lineatext;
                                #print $lineaseg;
                                print "\n";
                                print F3 $lineatext;
                                                   
                                                        }
close (F3);                                     }
close (F);
close (F2);


 
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
guillermelc
Perlero nuevo
Perlero nuevo
 
Mensajes: 7
Registrado: 2007-11-13 12:33 @565

Notapor explorer » 2007-12-01 10:14 @468

Tienes mal colocados los close().

Qué digo... creo que hay un pequeño lío con los open, los print y los close...
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: Google [Bot] y 0 invitados

cron