• Publicidad

Desglosar cadena de palabras y asignarle una variable

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

Desglosar cadena de palabras y asignarle una variable

Notapor Carlos2012 » 2012-03-09 15:15 @677

Buenas tardes compañeros,

tengo una pequeña cuestión con la que no he podido localizar respuesta alguna.
Necesito poder leer una frase que se ha introducido en un cuestionario html, desglosar esa frase en cada una de las palabras que la forman, y luego asignarles una variable a cada una de dichas palabras.


Sintáxis: [ Descargar ] [ Ocultar ]
  1. #!/usr/bin/perl  
  2. use CGI;  
  3.  
  4. my $q=new CGI;  
  5. my $consulta;  
  6.  
  7. print $q->header("text/html");  
  8. print $q->start_html(-title=>"Tu pregunta");  
  9. print"\n";  
  10.  
  11. $consulta =$q->param('consulta'); 
  12.  
  13. # aquí desglosaría la pregunta (frase en las distintas palabras que la forman y se le asignaría una variable de  
  14. texto) 
  15.  
  16. print" Tu consulta es: $palabra1 $palabra2 $palabra3 $palabra4, \n";  
  17. print $q->end_html(); 


El problema es que no puedo tomar la entrada $consulta como un array, y descomponerlo porque no sé a priori cuántas palabras forman la pregunta y no sé cuántas variables necesitaría crear para cada una de dichas palabras.

Bueno, creo que la duda está más o menos clara.

Agradecido vuestros comentarios, os mando un abrazo. :D

SalU2.
Carlos2012
Perlero nuevo
Perlero nuevo
 
Mensajes: 10
Registrado: 2012-03-03 13:28 @603

Publicidad

Re: Desglosar cadena de palabras y asignarle una variable

Notapor explorer » 2012-03-09 15:23 @682

Tienes una primera solución en perlfaq6, en tu propio ordenador: perldoc perlfaq6 (busca por How do I process each word on each line?. Mira también la siguiente pregunta a esta, que quizás también te interese: How can I print out a word-frequency or line-frequency summary?).

Ahí verás cómo dividir una línea y usar cada palabra en un bucle for(), pero de la misma manera puedes guardar las palabras en un array, que es la respuesta a tu inquietud sobre desconocer a priori el número de variables que vas a necesitar. Mejor guardar toda la información en una estructura de tipo vector o matriz.
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

Re: Desglosar cadena de palabras y asignarle una variable

Notapor Carlos2012 » 2012-03-11 05:18 @263

Buenas..

Muchas gracias por tu respuesta explorer. El caso es que ya he podido conseguir desglosar la entrada en sus palabras correspondientes con el uso de

Sintáxis: [ Descargar ] [ Ocultar ]
  1. #!/usr/bin/perl 
  2.  
  3. use CGI;  
  4. use strict; 
  5. use warnings; 
  6.  
  7. my $q=new CGI;  
  8. my $consulta;  
  9.  
  10. print $q->header("text/html");  
  11. print $q->start_html(-title=>"Tu pregunta");  
  12. print"\n";  
  13. $consulta =$q->param('consulta');  
  14.  
  15. my @frase = split(/ /,$consulta); 
  16.  
  17.  foreach my $palabras (@frase) { 
  18.   print "$palabras\n"; 
  19.  } 
  20.  
  21. print $q->end_html(); 
  22. exit 0; 


El caso es que puedo conseguir desglosar la frase en palabras pero no sé cómo asignar a cada una de esas palabras una variable tipo $palabra1, $palabra2, .. $palabraN. Una posible solución es contar cuántas palabras hay en la frase (creo que sé cómo se hace), pero no sabría seguir.
Por otro lado, ¿puedo realizar un split/PATTERN/,EXPR en donde el PATTERN sean varias condiciones (varios caracteres en el que se dan todos o solamente alguno de ellos) o sería en este caso utilizar varios if para cada uno de los split? (esto último lo probé pero al final sólo obtenía el resultado del último if).

Muchas gracias por vuestros comentarios. :wink:

SalU2.
Carlos2012
Perlero nuevo
Perlero nuevo
 
Mensajes: 10
Registrado: 2012-03-03 13:28 @603

Re: Desglosar cadena de palabras y asignarle una variable

Notapor Carlos2012 » 2012-03-11 16:36 @733

Buenas de nuevo,

he ido avanzando un poco en el proceso que quiero realizar, y aquí os dejo mi último código:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5. use DBI;
  6.  
  7. print "\nPregunta lo que deseas saber\n";
  8. print "\n";
  9. my $consulta = <STDIN>;
  10. my $numpalabras;
  11. my @palabras = split( / /, $consulta );
  12. my $i = 0;
  13. my @tupla;
  14. my $sth;
  15.  
  16. $numpalabras = $#palabras + 1;
  17.  
  18. print "el número de palabras es $numpalabras \n";
  19.  
  20. for ( my $i = 0; $i <= $numpalabras - 1; $i++ ) {
  21.     print "la palabra $i es $palabras[$i] \n";
  22. }
  23.  
  24. #Usamos las librerias de acceso a BD
  25.  
  26. my $base_datos = "personajes";         #Nombre de las base de datos
  27. my $usuario    = "root";               #Usuario de la BD
  28. my $clave      = "xxxxx";              #Password de la BD
  29. my $driver     = "mysql";              #Utilizamos el driver de mysql
  30. my $tabla      = "ciencia";            #Nombre de la tabla de ejemplo
  31.  
  32. #Conectamos con la BD, si no podemos, ponemos un mensaje de error
  33. my $dbh = DBI->connect( "dbi:$driver:$base_datos", $usuario, $clave )
  34.     || die "\nError al abrir la base datos: $DBI::errstr\n";
  35.  
  36. for ( my $i = 0; $i <= $numpalabras - 1; $i++ ) {
  37.  
  38.     my $sth = $dbh->prepare("SELECT texto FROM ciencia WHERE nombre='$palabras[$i]';");
  39.  
  40.     #Realizamos la etapa de ejecución de la sentencia
  41.     $sth->execute();
  42.  
  43.     #Realizamos la etapa de extracción de datos. Imprimimos tupla a tupla.
  44.     while ( @tupla = $sth->fetchrow_array() ) {
  45.         print "$tupla[0]\n";
  46.     }
  47.  
  48. }
  49.  
  50. #Realizamos la etapa de liberación de recursos ocupados por la sentencia
  51. $sth->finish();
  52.  
  53. #Nos desconectamos de la BD. Mostramos un mensaje si hay
  54. #algun fallo
  55. $dbh->disconnect || warn "\nFallo al desconectar.\nError: $DBI::errstr\n";
  56.  
  57. print " \n";
  58.  
  59. exit 0;
  60.  
  61.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Como veis realizo una búsqueda de cada una de las palabras que forman la entrada al programa y las comparo con un campo de la base de datos. El caso es que me sale un error de tipo:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Can't call method "finish" on an undefined value at consulta2.pl line 51, <STDIN> line 1.
 
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


¿Podríais indicarme qué es lo que está incorrecto en el código?

Muchas gracias por vuestra ayuda. :D

SalU2.
Carlos2012
Perlero nuevo
Perlero nuevo
 
Mensajes: 10
Registrado: 2012-03-03 13:28 @603

Re: Desglosar cadena de palabras y asignarle una variable

Notapor explorer » 2012-03-12 10:01 @459

Al formatear el código con perltidy se ve claramente lo que pasa: la variable $sth está definida dentro del bucle for(), así que no es conocida fuera de él.

Debes meter la línea 51 en la 47.
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

Re: Desglosar cadena de palabras y asignarle una variable

Notapor Carlos2012 » 2012-03-12 11:58 @540

Debe de haber algo raro con $palabras[$i] porque ahora con el cambio que me has comentado no me da error, pero en cambio no muestra nada de la base de datos. Si en vez de $palabras[$i] pongo una palabra del campo nombre de la BBDD, no me da error, por lo que deduzco que el problema debe estar en la sentencia $palabras[$i] dentro de la línea de
Sintáxis: [ Descargar ] [ Ocultar ]
  1. my $sth = $dbh->prepare("SELECT texto FROM ciencia WHERE nombre='$palabras[$i]';"); 


Estoy probando con variaciones, pero nada... :(

¿Algo que se escapa? ¿o quizás otra forma de hacerlo?

SalU2.
Carlos2012
Perlero nuevo
Perlero nuevo
 
Mensajes: 10
Registrado: 2012-03-03 13:28 @603

Re: Desglosar cadena de palabras y asignarle una variable

Notapor explorer » 2012-03-12 12:44 @572

Queda mucho más simple así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. for my $palabra (@palabras) {
  2.     my $sth = $dbh->prepare("SELECT texto FROM ciencia WHERE nombre=?");
  3.  
  4.     $sth->execute($palabra);
  5.  
  6.     # (aquí extraemos el resultado...)
  7.  
  8. }
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

Re: Desglosar cadena de palabras y asignarle una variable

Notapor Carlos2012 » 2012-03-13 14:51 @660

Buenas de nuevo...

Algo parece funcionar mal ya que al poner

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $dbh = DBI->connect( "dbi:$driver:$base_datos", $usuario, $clave )
  2.     || die "\nError al abrir la base datos: $DBI::errstr\n";
  3.  
  4. for my $palabra (@palabras) {
  5.     my $sth = $dbh->prepare("SELECT texto FROM ciencia WHERE nombre=?");
  6.  
  7.     $sth->execute($palabra);
  8.  
  9.     while ( @tupla = $sth->fetchrow_array() ) {
  10.         print "$tupla[0]\n";
  11.     }
  12.  
  13.     $sth->finish();
  14. }
  15.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


No da error de código, pero no muestra nada de la BBDD. He estado probando varias cosas, pero sigo sin tener el resultado deseado... :(

¿Se nos escapa algo? Gracias.

SalU2.
Carlos2012
Perlero nuevo
Perlero nuevo
 
Mensajes: 10
Registrado: 2012-03-03 13:28 @603

Re: Desglosar cadena de palabras y asignarle una variable

Notapor explorer » 2012-03-13 16:30 @729

Yo no veo nada raro. El única cambio cosmético es el de cambiar '||' por el más correcto 'or'. Pero eso tampoco influye en el resto del código.

Voy a decir que
* el usuario no tiene permisos para hacer SELECT a la base de datos
* la tabla ciencia no existe
* el campo texto y/o nombre no existen

Esta otra variación también debería funcionar:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $dbh = DBI->connect( "dbi:$driver:$base_datos", $usuario, $clave )
  2.        or die "\nError al abrir la base datos: $DBI::errstr\n";
  3.  
  4. my $sth = $dbh->prepare("SELECT texto FROM ciencia WHERE nombre=?");
  5.  
  6. print "Número de palabras a buscar: [", scalar(@palabras), "]\n";
  7.  
  8. for my $palabra (@palabras) {
  9.     $sth->execute($palabra);
  10.     while ( @tupla = $sth->fetchrow_array() ) {
  11.         print "$tupla[0]\n";
  12.     }
  13. }
  14.  
  15. $sth->finish;
  16. $dbh->disconnect;
  17.  
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

Re: Desglosar cadena de palabras y asignarle una variable

Notapor Carlos2012 » 2012-03-14 15:08 @672

Muchas gracias, explorer..

Finalmente he descubierto qué pasaba. Te cuento: si la consulta es "Dime quién fue Tesla", no produce ningún resultado. Si en vez de eso pongo "Tesla dime quién es" sí me da el resultado. Es decir, si la palabra que está en la BBDD (Tesla) se pone al principio de la frase o en cualquier otro menos justo la última, da el resultado, pero si se pone al final de la frase, ¡¡no sale nada!! :shock: :shock:

¿Cosa más rara, no? :? Creo que la clave está en
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. for my $palabra(@palabras) {
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
. ¿¿ Habría que ponerle un contador +1 ??

SalU2.
Carlos2012
Perlero nuevo
Perlero nuevo
 
Mensajes: 10
Registrado: 2012-03-03 13:28 @603

Siguiente

Volver a Básico

¿Quién está conectado?

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

cron