Página 1 de 1

Extraer palabras con múltiples opciones

NotaPublicado: 2016-08-05 16:30 @729
por abraham03
Hola.

¿Cómo hago para agregar una búsqueda y extracción de diferentes combinaciones de palabras?

Tengo un archivo de texto como este:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
#name_file
Bacteria;WS3;PRR-12;SSS58A      0.0     0.12    0.6
Bacteria;WS3;PRR-12;Sediment-1  0.5     0.1     0.3
Bacteria;Terrabacteria_group;Firmicutes;Bacilli; unclassified_Bacillales;Bacillaceae;Vulcanibacillu     0.2     0.2     0.6
Bacteria;Terrabacteria_group;Firmicutes;Bacilli;Bacillales;Bacillaceae;Vulcanibacillu   0.2     0.2     0.6
Bacteria;Terrabacteria_group;Firmicutes;Bacilli;Bacillales;Bacillales_incertae_sedis;Bacillales_Family_X        0.1     0.3     0.5
Bacteria;Terrabacteria_group;Firmicutes;Bacilli;Bacillales;Bacillales_incertae_sedis;Bacillales_Family_X._Incertae_Sedis;Thermicanus    0.4     0.13    0.9
Bacteria;Nitrospirae;Nitrospira;Nitrospirales;Thermodesulfovibrionaceae 0.1     0.2     0.6
Bacteria;Nitrospirae;Nitrospira;Nitrospirales;Thermodesulfovibrionaceae;BD2-6   0.0     0.0     0.6
Bacteria;PVC_group;Lentisphaerae;Lentisphaeria;Lentisphaerales  0.7     0.2     0.1
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

y quiero extraer la primera, y si existe, una segunda palabra (pero no la tercera) que tenga la terminación en 'ales' de cada línea y que se imprima como
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
 Bacillales
 Bacillales;Bacillales_incertae_sedis
 Bacillales;Bacillales_incertae_sedis
 Nitrospirales
 Nitrospirales
 Lentisphaerales
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

La segunda siempre termina como estos ejemplos:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Bacillales_incertae_sedis, Nitrospirales_incertae_sedis
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

es decir: \w*ales_incertae_sedis
Ignorar si presenta una tercera como aparece en Bacillales_Family.

El problema que tengo es una coincidencia con múltiples opciones en la línea
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my (@orden) = ($taxon=~ m/(\w*ales)[\;]?/g)
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Este es el código:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use strict;
  2.  
  3. use warnings;
  4.  
  5. use Getopt::Long;
  6.  
  7. GetOptions( 'i=s' => \$infile, );
  8.  
  9. open INFILE, '<', "$infile", or die "cant open file $infile";
  10.  
  11. open OUTFILE, '>', "$results.txt" or die "cant open";
  12.  
  13. while (<INFILE>) {
  14.     my $line = $_;
  15.     chomp($line);
  16.  
  17.     if ( $line =~ m/^#/g ) {
  18.         next;
  19.     }
  20.  
  21.     elsif ( $line =~ m/^$/g ) {
  22.         next;
  23.     }
  24.  
  25.     elsif ($line) {
  26.         my @taxonomic = $_;
  27.         foreach (@taxonomic) {
  28.             ( $taxon, $val1, $val2, $val3 ) = split( /\t/, $_ );
  29.         }
  30.  
  31.         # here is the problem
  32.         my (@orden) = ( $taxon =~ m/(\w*ales)[\;]?/g );
  33.         foreach (@orden) {
  34.             if ( $_ =~ m/^$/g ) {
  35.                 next;
  36.             }
  37.             elsif ( $_ =~ m/^unclassified/g ) {
  38.                 next;
  39.             }
  40.  
  41.             else {
  42.                 print OUTFILE "$_\n";
  43.             }
  44.         }
  45.         close INFILE;
  46.         close OUTFILE;
  47.         exit;
  48.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


He intentado esto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.     my (@orden) = ($taxon=~ m/(\w*ales)[\;]?(;\w*ales_incertae_sedis)/g);
  2.     my (@orden) = ($taxon=~ m/(\w*ales[;\w*ales_incertae_sedis]?)[\;]?/g);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

pero no me resuelve el problema.

Muchas gracias.

Re: Extraer palabras con múltiples opciones

NotaPublicado: 2016-08-05 22:09 @964
por explorer
No estoy seguro de entender las premisas, pero el siguiente código saca la salida pedida:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/env perl
  2. use strict;
  3. use warnings;
  4. use autodie;
  5.  
  6. open my $INFILE, '<', "taxones.txt";
  7.  
  8. while (my $linea = <$INFILE>) {
  9.     chomp $linea;
  10.     next if not $linea  or  $linea =~ /^#/;
  11.  
  12.     my ($taxon, $val1, $val2, $val3) = split /\t/, $linea;
  13.  
  14.     my @ordenes = split /[;]/, $taxon;
  15.  
  16.     my @interesa;
  17.  
  18.     for my $orden (@ordenes) {
  19.         if ($orden =~ /^\w+ales(?:_incertae_sedis)?$/) {
  20.             push @interesa, $orden;
  21.         }
  22.     }
  23.  
  24.     # print "[$linea]\n";
  25.     print join(";", @interesa), "\n" if @interesa;
  26. }
  27.  
  28. close $INFILE;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Recorremos las distintas partes de @ordenes, que es la parte del $taxon, pero partíendolo por los ';'.
Por cada uno de ellos, comprobamos si satisface la expresión regular, que es $orden =~ /^\w+ales(?:_incertae_sedis)?$/, que quiere decir:
  • desde el principio (^) hasta el final ($), $orden debe consistir en
  • uno o más caracteres alfanuméricos (\w+) seguidos por 'ales'
  • opcionalmente (?) seguidos por '_incertae_sedis' (la expresión '?:' indica que los paréntesis no capturan, solo agrupan)
Si encontramos lo que queremos, lo guardamos en @interesa. La salida es idéntica a lo que mostrabas.

Pero no sé si he interpretado bien algunas cosas, como por ejemplo, "quiero extraer la primera, y si existe, una segunda palabra (pero no la tercera)".

Re: Extraer palabras con múltiples opciones

NotaPublicado: 2016-08-09 11:06 @504
por abraham03
Muchas gracias, lo voy a implementar :)

Sí, de hecho interpretaste bien: sale justo como lo quería.

Oye: siempre he seguido tus comentarios en el foro. Cuando respondes a otras personas siempre se me ha hecho muy limpio y sencillo tu manera de programar.

¿De casualidad tendrás algún manual hecho por ti mismo que me pudieras facilitar? Creo que me sería de gran utilidad.

Saludos y muchas gracias.

Abraham

Re: Extraer palabras con múltiples opciones

NotaPublicado: 2016-08-10 07:12 @342
por explorer
Mi forma de programar es el resultado de:
  • leer mucho código de otras personas, y fijarme en cómo lo han hecho. Aprender de los aciertos de los buenos y de los errores de los malos
  • leer el libro "Perl Best Practices", de Damian Conway.