Página 2 de 3

Re: Acumulación de texto

NotaPublicado: 2012-05-15 13:12 @592
por gallinaclueca
Perdón, me confundí de código. El código que tengo para este problema es este. La duda que tengo es como representar el "espacio en blanco" en if ($linea2 =~ "CTA TGA") pues si pongo solo CTA me devuelve el resultado positivo, pero si hay espacio en medio no, y sí que hay en el archivo de texto.

$contador = 0;
@codones = ();
while ($contador < 20){
$contador += 1;
$espermatozoide = "espermatozoide$contador.txt";
open (FH, "$espermatozoide") or die "No se puede abrir";
open (FH2, " > result$contador.txt");
while ( $linea = <FH> ){
$codon = substr ($linea, 0, 3);
push (@codones, $codon);
print FH2 "@codones ";
}
@codones = ();
}
print "Hecho\n";
close (FH);
close (FH2);
$contador2 = 0;
while ($contador2 < 20) {
$contador2 += 1;
$result = "result$contador.txt";
open (FH2, "$result") or die "No se pudo abrir el archivo";
open (FH3, " > aminoacidos$contador2.txt");
while ($linea2 = <FH2>) {
if ($linea2 =~ "CTT TGA") {
print FH3 "Tenemos Alanina\n";
}
}
}
close (FH2);
close (FH3);

Re: Acumulación de texto

NotaPublicado: 2012-05-15 13:26 @601
por explorer
Es que no estás haciendo una expresión regular. Aunque estés usando el operador =~, en la parte derecha no hay un operador que contenga un patrón. Tienes puesto una simple cadena de caracteres.

Entonces, debes hacerlo de una de estas dos formas:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. while ( $linea2 = <FH2> ) {
  2.     if ( $linea2 =~ /CTT TGA/ ) {
  3.         print FH3 "Tenemos Alanina\n";
  4.     }
  5. }
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. while ( $linea2 = <FH2> ) {
  2.     if ( index($linea2, 'CTT TGA') > -1 ) {
  3.         print FH3 "Tenemos Alanina\n";
  4.     }
  5. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

La más rápida y eficiente es la segunda, ya que solo realiza una búsqueda lineal, sin tener que recrear un patrón de expresión regular.

P.D. Acostúmbrate, por favor, en marcar tu código Perl. Hay un botón llamado así, mientras estás editando los mensajes. Así, el código sale en fuente monoespaciada y con colorines. ¿No te gustan los colorines :?:

Re: Acumulación de texto

NotaPublicado: 2012-05-15 13:36 @608
por gallinaclueca
He probado de ambas formas y sigue sin funcionarme. En los archivos aminoacido$contador2 correspondientes al filehandle FH3 no se me guarda nada en ninguno de los 20 y al menos en el 1, hay una secuencia 'CTT TGA'.

Re: Acumulación de texto

NotaPublicado: 2012-05-18 10:04 @461
por gallinaclueca
Si ninguna de tus formas funciona, ¿cómo hago para que me reconozca el if() una porción de texto separada por espacios?

Re: Acumulación de texto

NotaPublicado: 2012-05-18 10:23 @474
por explorer
m/texto1\s+texto2/

El '\s+' quiere decir "uno o más de caracteres catalogados como 'espacio en blanco'".

Si no te funcionan mis soluciones, es porque Perl no ha encontrado esos patrones en las líneas que has leído.

A mí, desde luego, sí que funcionan... pero es porque en las pruebas tengo alguna línea que coincide con ese patrón.

Re: Acumulación de texto

NotaPublicado: 2012-05-18 10:53 @495
por gallinaclueca
No sé en qué consiste esto del '\s+' :S ¿cómo lo utilizo? Me refiero a que yo quiero que si el archivo tiene la secuencia de texto 'CTT TGA' me haga la condición del if(). ¿Cómo aplico la expresión '\s+' para hacer esto?

Re: Acumulación de texto

NotaPublicado: 2012-05-18 11:44 @531
por explorer
El patrón '\s+' solo tiene significado dentro de una expresión regular, así que tienes que aplicarlo así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. while ( $linea2 = <FH2> ) {
  2.     if ( $linea2 =~ /CTT\s+TGA/ ) {
  3.         print FH3 "Tenemos Alanina\n";
  4.     }
  5. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Dices que con un solo carácter espacio no te ha funcionado, así que con '\s+' esperamos detectar más de un carácter en blanco (tabuladores y retornos de carro incluidos).

Quizás sería más fácil si nos mandarás un adjunto con unas pocas líneas de cómo es la entrada que quieres procesar. Así veríamos si hay espacios en blanco u otra cosa.

P.D. ¿seguro que lo que buscas está en mayúsculas? A ver si va a ser eso...

Re: Acumulación de texto

NotaPublicado: 2012-05-18 12:00 @541
por gallinaclueca
Sigue sin funcionarme lo que me dices :S pero he conseguido resolverlo mediante concatenación.

He hecho esto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. if ($linea2 =~ "GAC"." "."GAT") {
  2.     print FH3 "Asp\n";
  3. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

De este modo sí me imprime Asp en el archivo aminoácidos.

(Aquí te pongo Asp del mismo modo que antes te ponía tenemos Alanina).

El problema no era cuestión de mayúsculas, ¡je,je! Malo fuera que no me hubiese dado cuenta de eso siendo una secuencia de bases nitrogenadas.

Pues va a ser que no funciona lo que acabo de poner pues aunque ponga letras que sé que no aparecen sigue imprimiéndome el resultado :shock: me estoy desesperando.

Te subo uno de los archivos de los que recogemos las bases para que lo veas a ver si el problema está ahí:

Re: Acumulación de texto

NotaPublicado: 2012-05-18 12:26 @560
por gallinaclueca
Me he dado cuenta de que poniendo entre paréntesis la condición if ($linea2 =~ (....)) solo nos reconoce un triplete (ej: reconoce CGA, pero no CGA ATT).

En cambio si no ponemos paréntesis, siempre nos imprime el resultado, se cumpla o no la condición (ej.: if ($linea2 =~ "CTA"." "."gato" Obviamente gato no está en el archivo pero aún así nos imprime el resultado) No entiendo nada :S

Re: Acumulación de texto

NotaPublicado: 2012-05-18 13:07 @588
por explorer
El problema es el siguiente: el archivo no tiene varias líneas, sino que solo tiene una línea.

Hay que hacer unos cambios...

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/env perl
  2. # Detector de tripletes de aminoácidos
  3. # Joaquín Ferrero, 20120518
  4. use strict;
  5. use warnings;
  6. use diagnostics;
  7. use autodie;                    # «Es mejor morir que regresar con deshonor» --proverbio Klingon
  8.  
  9. my %tripletes = (
  10.     'CAG TTA' => 'Alanina',
  11.     'CTT TGA' => 'Alanina',
  12.     'GAC GAT' => 'Asp',
  13. );
  14.  
  15. open my $SEQS, '<', 'result1.txt';
  16.  
  17. while (my $linea = readline $SEQS) {                    # para todas las líneas del archivo (si hubieran)
  18.     chomp $linea;
  19.  
  20.     for my $triplete (keys %tripletes) {                # para todos los tripletes que buscamos
  21.  
  22.         my $pos = index $linea, $triplete;
  23.  
  24.         if ($pos != -1) {                               # ¿hay alguno?
  25.  
  26.             print "contiene $tripletes{$triplete} en posición $pos\n";
  27.         }
  28.     }
  29. }
  30.  
  31. close $SEQS;
  32.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Con este programa, sale el siguiente resultado:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
contiene Asp en posición 7072
contiene Alanina en posición 52
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Usamos un hash para relacionar los tripletes que buscamos con el nombre que queremos imprimir.
Leemos cada línea del archivo de entrada (aunque sabemos que solo hay una), y por cada triplete a buscar, lo hacemos con index(), que nos localiza rápidamente lo que queremos.

Y en cuanto a que te sale una cosa distinta cada vez que pruebas... pues porque Perl es muy liberal en cuanto a lo que admite como sintaxis correcta, pero no siempre lo que escribimos es lo que queremos que Perl haga. Hay que escribir siempre la sintaxis correcta. Y las expresiones regulares tienen sus reglas.