2009-05-07 4 views
4

Je parcourt un fichier et sur chaque ligne je recherche une regex. Si l'expression rationnelle est trouvée, je veux juste imprimer "c'est trouvé" et ensuite l'emplacement de l'index où il a été trouvé dans cette ligne.Comment trouver l'emplacement d'index d'une sous-chaîne correspondant à une regex en Perl?

Exemple:

looking for: 'HDWFLSFKD' need index between two Ds 
line: MLTSHQKKF*HDWFLSFKD*SNNYNSKQNHSIKDIFNRFNHYIYNDLGIRTIA 
output: 'its found' index location: 10-17 

ci-dessus « recherche » est tout à fait simple, mais je prévois d'avoir des déclarations regex complexes là-dedans.
Donc, fondamentalement, je veux juste savoir si une regex est trouvée dans une chaîne, alors comment pouvons-nous obtenir l'emplacement de l'index?

Voici le code que j'ai jusqu'à présent:

foreach my $line (@file_data) 
{ 
     if ($line=~ /HDWFLSFKD/){ 
      print "it's found\n"; 
      print "but at what index are the two Ds"; 
      } 
     else { 
      $sequence.=$line; 
      print "came in else\n"; 
     } 
} 
+0

est-ce pas un double de http://stackoverflow.com/ questions/87380/comment-puis-je-trouver-la-localisation-d'une-regex-match-en-perl? –

Répondre

13

Je crois que vous cherchez pos:

#!/usr/bin/perl 

use strict; 
use warnings; 

my $sequence; 
while (my $line = <DATA>) { 
    if ($line=~ /(HDWFLSFKD)/g){ 
     print "its found index location: ", 
      pos($line)-length($1), "-", pos($line), "\n"; 
    } else { 
     $sequence .= $line; 
     print "came in else\n"; 
    } 
} 

__DATA__ 
MLTSHQKKF*HDWFLSFKD*SNNYNSKQNHSIKDIFNRFNHYIYNDLGIRTIA 
MLTSHQKKFSNNYNSKQNHSIKDIFNRFNHYIYNDLGIRTIA 
MLTSHQKKFSNNYNSK*HDWFLSFKD*QNHSIKDIFNRFNHYIYNDLGIRTIA 

Vous pouvez également utiliser les @- et @+ variables:

#!/usr/bin/perl 

use strict; 
use warnings; 

my $sequence; 
while (my $line = <DATA>) { 
     if ($line=~ /HDWFLSFKD/){ 
       print "its found index location: $-[0]-$+[0]\n"; 
     } else { 
       $sequence .= $line; 
       print "came in else\n"; 
     } 
} 

__DATA__ 
MLTSHQKKF*HDWFLSFKD*SNNYNSKQNHSIKDIFNRFNHYIYNDLGIRTIA 
MLTSHQKKFSNNYNSKQNHSIKDIFNRFNHYIYNDLGIRTIA 
MLTSHQKKFSNNYNSK*HDWFLSFKD*QNHSIKDIFNRFNHYIYNDL 
+0

sont les mêmes fonctions pos et @position? –

+0

Que fait 1 $? –

+1

$ 1 détient la première capture. Je l'utilise parce que je ne veux pas coder en dur la longueur de la chaîne de recherche. La fonction pos vous indique où la dernière correspondance s'est arrêtée dans une chaîne donnée. Les tableaux @ - et @ + sont définis respectivement au début et à la fin des correspondances. $ - [0], $ + [0] sont le début et la fin du match entier, $ - [1], $ + [1] sont le début et la fin de la première capture, $ - [2], $ + [2] est la deuxième capture, et ainsi de suite. –

0

Vous pouvez diviser votre chaîne avec l'expression rationnelle et la sortie de la taille du premier élément de tableau, s'il y a plus d'un elemnts dans le tableau. Un simple exemple:

my $test="123;456"; 
my @help=split(';', $test); 
if ($#help>0) { 
    print "Index is:".length($help[0]); 
} 

Edit: Cela correspond à votre exemple simple, mais pas complètement avec votre texte - si le regex est plus complexe, la taille des critères fendus obtient à nouveau flexible. Ensuite, vous devez déterminer l'indice du second élément du tableau pour déterminer la taille du critère de partage.

+1

Je ne pense pas que ça va marcher. Dans ce cas, vous vous attendez à ce que mon expression régulière corresponde au début de la chaîne. –

+0

Ceci est un cas supplémentaire qui n'est pas couvert correctement - la condition correcte serait alors que le premier élément du tableau est différent de la chaîne d'origine et l'index correct est la différence de la longueur entre le premier élément du tableau et la chaîne originale . – weismat

Questions connexes