Página 1 de 1

Problema con expresión regular

NotaPublicado: 2013-04-09 10:49 @492
por anfelvas
Hola, estoy teniendo problemas con un script para rescatar una expresión regular que es correspondiente a un identificador:

En el archivo original, luciría así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
MOLECULE
CARBON65005451
   45   67   89
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


y sigue ofreciendo más información para cada molécula. Si su id number (CARBON65005451 en este caso) es mencionada solo una vez en el archivo, ¿cómo puedo usar una expresión regular correctamente para meter todos los id numbers en una especie de lista (arreglo, supongo) y exportarlo a otro archivo?

Resumiendo, el script va hasta acá:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. #idsearch.pl
  3. #use strict;
  4. #use warnings;
  5.  
  6. open FILE, $ARGV[0];
  7. while (my $line = <>){
  8. if ($line = ~/^\n(CARBON\d+)\n){
  9. @ids=($_)
  10.  
  11.  
  12. OPEN LIST, $ARGV[1];
  13. print @ids
  14.  
  15. CLOSE FILE;
  16. CLOSE LIST;
Coloreado en 0.005 segundos, usando GeSHi 1.0.8.4


Agradezco de antemano cualquier ayuda.

Andres F.

Re: Problema con expresión regular

NotaPublicado: 2013-04-09 13:18 @596
por explorer
Bienvenido a los foros de Perl en Español, anfelvas.

Sí que veo problemas...

  • con el while estamos leyendo líneas completas, así que no tiene sentido, en la expresión regular, buscar por '\n' al principio del patrón. Tampoco es necesario el último, porque solo nos interesa el id, nada más
  • en la línea 9 intentas guardar el código encontrado, pero en lugar de eso solo estás reescribiendo todo el contenido del array, con un array que solo tiene un valor: el de la variable $_, que ahí mismo no sabemos el valor que tiene
  • Las líneas 12, 15 y 16 están mal: los nombres de las funciones son open y close, en minúsculas
Esta es una posible solución:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. #idsearch.pl
  3. use strict;       # programación estricta
  4. use warnings;     # activar las advertencias
  5. use diagnostics;  # activar aún más advertencias
  6. use autodie;      # mejor morir que regresar con deshonor
  7.      
  8. my @ids;
  9.  
  10. open my $FILE, $ARGV[0];               # abrimos el archivo
  11. while (my $line = <$FILE>) {           # mientras no lleguemos al final del archivo, leer una línea
  12.     chomp $line;                       # le quitamos el carácter o caracteres de fin de línea
  13.  
  14.     if ($line =~ /^(CARBON\d+)/) {     # si la línea comienza por 'CARBON' seguido por unos números
  15.         push @ids, $1;                 # metemos (push) el id dentro del array
  16.     }
  17. }
  18. close $FILE;
  19.  
  20. open my $LIST, ">$ARGV[1]";            # abrimos el segundo archivo en modo escritura
  21. foreach my $id (@ids) {                # para cada $id sacado de @ids
  22.     print $LIST "$id\n";               # lo imprimimos, con un carácter de nueva línea
  23. }
  24. close $LIST;
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Re: Problema con expresión regular

NotaPublicado: 2013-04-09 13:42 @612
por Dshellnoi_Unix
explorer, eres un rayo, estaba todo motivado que esta me la sabía yo. Me quedé en palanca ¡ja,ja,ja,ja! :D

Re: Problema con expresión regular

NotaPublicado: 2013-04-09 14:03 @627
por explorer
Puedes enviar tu solución.

Este es un problema que se puede resolver de muchas formas.

Re: Problema con expresión regular

NotaPublicado: 2013-04-09 16:21 @723
por anfelvas
Hola. Gracias por su respuesta. Ha sido muy clara y elegante.

Ahora trato de perfeccionar el script, permitiendo que en el archivo de salida:
1- Se obtenga el número total de elementos del arreglo (¿cómo se obtienen registros únicos en el caso de que repitieran en el archivo que se analiza?)
2- Se obtenga un elemento del arreglo por azar (elección aleatorizada)

El script luce así ahora:

#!/usr/bin/perl -w
#idsearch.pl
use strict; # programación estricta
use warnings; # activar las advertencias
use diagnostics; # activar aún más advertencias
use autodie; # mejor morir que regresar con deshonor

if(@ARGV!=2){die "must supply exactly two arguments\n"} #control de entrada de usuario: que se reciben exactamente dos archivos

if(!-s $ARGV[0]){
die "Provide the input file with data\n";
} #control de entrada de usuario: que el archivo de entrada que se recibe exista y tenga datos

my @ids;
open my $FILE, $ARGV[0]; # abrimos el archivo
while (my $line = <$FILE>) { # mientras no lleguemos al final del archivo, leer una línea
chomp $line; # le quitamos el carácter o caracteres de fin de línea

if ($line =~ /^(CARBON\d+)/) { # si la línea comienza por 'CARBON' seguido por unos números
push @ids, $1; # metemos (push) el id dentro del array
}
}
close $FILE;

open my $LIST, ">$ARGV[1]"; # abrimos el segundo archivo en modo escritura
foreach my $id (@ids) { # para cada $id sacado de @ids
print $LIST "$id\n"; # lo imprimimos, con un carácter de nueva línea

$idsize = scalar (@ids); # ¿contar el número únicos de elementos del arreglo?
$idsize = $#ids + 1;
print "$idsize\n";

my $item = int(rand(@ids)); # ¿obtener al azar un solo elemento del arreglo (es decir, un id)?
print "$item\n";
}
close $LIST;

Gracias de antemano por su revisión del script.

Andrés F.

Re: Problema con expresión regular

NotaPublicado: 2013-04-09 16:39 @735
por explorer
Para obtener valores únicos, solemos usar un hash.

Y la obtención del número aleatorio es correcta: con ese código obtienes un valor aleatorio entre los índices del array @ids. Solo te falta acceder al elemento indexado por ese índice. Por ejemplo: print $ids[$item], "\n";

Re: Problema con expresión regular

NotaPublicado: 2013-04-09 16:56 @747
por anfelvas
Gracias por tu ayuda. No obstante, el archivo de salida queda vacío (0 KB). ¿Es posible que sea necesario declarar las variables (como $idsize) fuera del foreach en $ARGV[1]?

Re: Problema con expresión regular

NotaPublicado: 2013-04-09 16:58 @748
por explorer
A lo mejor te falta poner el $LIST, para indicar que la salida sea hacia al archivo.

print $LIST $ids[$item], "\n";

Re: Problema con expresión regular

NotaPublicado: 2013-04-09 18:36 @816
por anfelvas
Ya solucioné el problema, sacando del foreach al resto del script que fue incluido. Mil gracias.

Re: Problema con expresión regular

NotaPublicado: 2013-04-09 18:42 @821
por explorer
Si pusieras el código Perl bien formateado, sería fácil ver esos errores ;)

En la edición de un mensaje fíjate en los botones que están por encima de la caja de edición. En el lado izquierdo está el de "Perl".