2009-05-07 7 views
1

以下は、文字列中の連続した部分文字列を見つけるためのスクリプトです。文字列とレコードの場所に複数の部分文字列を見つける

use strict; 
use warnings; 

my $file="Sample.txt"; 
open(DAT, $file) || die("Could not open file!"); 

#worry about these later 
#my $regexp1 = "motif1"; 
#my $regexp2 = "motif2"; 
#my $regexp3 = "motif3"; 
#my $regexp4 = "motif4"; 

my $sequence; 

while (my $line = <DAT>) { 
    if ($line=~ /(HDWFLSFKD)/g){ 
     { 
     print "its found index location: ", 
     pos($line), "-", pos($line)+length($1), "\n";   
     } 
     if ($line=~ /(HD)/g){ 
       print "motif found and its locations is: \n"; 
       pos($line), "-", pos($line)+length($1), "\n\n"; 
       } 
       if ($line=~ /(K)/g){ 
         print "motif found and its location is: \n"; 
         pos($line), "-",pos($line)+length($1), "\n\n"; 
         } 
         if ($line=~ /(DD)/g){ 
           print "motif found and its location is: \n"; 
           pos($line), "-", pos($line)+length($1), "\n\n"; 
           } 
}else { 
     $sequence .= $line; 
     print "came in else\n"; 
    } 
} 

substring1とstringが一致し、substring1が一致する位置が出力されます。問題は残りの部分文字列を見つけることにあります。 substrings2の場合、substring1が見つかった位置から開始する代わりに、文字列の先頭からやり直します。問題は、位置を計算するたびに、以前に見つかった部分文字列の位置から開始するのではなく、文字列の先頭から開始することです。部分文字列は部分文字列1、部分文字列2、部分文字列3、部分文字列4であるため、その位置は前の文字列の後になければなりません。

+1

あなたのコードには、角かっこの開閉に関する問題があるようです。これを整理するためにインデントを修正してください。 – Svante

+1

最近のPerlの質問のほとんどは、さまざまなコンテキストで正規表現を中心に展開しています。そのような質問にすばやく答える方法を見つけることができますか? – innaM

+0

perldoc perlretutを1〜2回読んで、必要に応じてperldoc perlrerefと相談すれば、すぐにこれらの質問のほとんどに答えが出ます。 –

答えて

1

いますが、$を使用することができます - 最後に見つかった正規表現のマッチのためのインデックスの場所を追跡し、$ +を: したがって以下は永遠に と一致しません。
以下は、これを説明するコードの上に構築されたコードです。

use strict; 
use warnings; 


my $file="sample.txt"; 
open(DAT, $file) || die("Could not open file!"); 

open (OUTPUTFILE, '>data.txt'); 

my $sequence; 
my $someVar = 0; 
my $sequenceNums = 1; 

my $motif1 = "(HDWFLSFKD)"; 
my $motif2 = "(HD)"; 
my $motif3 = "(K)"; 
my $motif4 = "(DD)"; 

while (my $line = <DAT>) 
{ 
    $someVar = 0; 
    print "\nSequence $sequenceNums: $line\n"; 
    print OUTPUTFILE "\nSequence $sequenceNums: $line\n"; 
     if ($line=~ /$motif1/g) 
     { 
       &printStuff($sequenceNums, "motif1", $motif1, "$-[0]-$+[0]"); 
       $someVar = 1; 
     } 


     if ($line=~ /$motif2/g and $someVar == 1) 
     { 
       &printStuff($sequenceNums, "motif2", $motif2, "$-[0]-$+[0]"); 
       $someVar = 2; 
     } 

     if ($line=~ /$motif3/g and $someVar == 2) 
     { 
       &printStuff($sequenceNums, "motif3", $motif4, "$-[0]-$+[0]"); 
       $someVar = 3; 
     } 

     if ($line=~ /$motif4/g and $someVar == 3) 
     { 
       &printStuff($sequenceNums, "motif4", $motif4, "$-[0]-$+[0]"); 
     } 

     else 
     { 
      $sequence .= $line; 

      if ($someVar == 0) 
      { 
       &printWrongStuff($sequenceNums, "motif1", $motif1); 
      } 
      elsif ($someVar == 1) 
      { 
      &printWrongStuff($sequenceNums, "motif2", $motif2); 
      } 
      elsif ($someVar == 2) 
      { 
      &printWrongStuff($sequenceNums, "motif3", $motif3); 
      } 
      elsif ($someVar == 3) 
      { 
      &printWrongStuff($sequenceNums, "motif4", $motif4); 
      } 
     } 
     $sequenceNums++; 
} 

sub printStuff 
{ 
      print "Sequence: $_[0] $_[1]: $_[2] index location: $_[3] \n"; 
      print OUTPUTFILE "Sequence: $_[0] $_[1]: $_[2] index location: $_[3]\n"; 
} 

sub printWrongStuff 
{ 
      print "Sequence: $_[0] $_[1]: $_[2] was not found\n"; 
      print OUTPUTFILE "Sequence: $_[0] $_[1]: $_[2] was not found\n";  

} 

close (OUTPUTFILE); 
close (DAT); 

サンプル入力:

MLTSHQKKF HDWFLSFKD SNNYN HD S K QNHSIK DD IFNRFNHYIYNDLGIRTIA MLTSHQKKFSNNYNSKQNHSIKDIFNRFNHYIYNDLGIRTIA MLTSHQKKFSNNYNSK HDWFLSFKD QNHSIKDIFNRFNHYIYNDL

1

あなたは本当にあなたが特別な変数@必要

を読んでください - あなたがポジションを必要とする場合と@ +を。自分で計算する必要はありません。

#!/usr/bin/perl 

use strict; 
use warnings; 

use List::MoreUtils qw(each_array); 

my $source = 'AAAA BBCCC DD E  FFFFF'; 
my $pattern = join '\s*', map { "($_+)" } qw(A B C D E F); 



if ($source =~ /$pattern/) { 
    my $it = each_array @-, @+; 

    $it->(); # discard overall match information; 

    while (my ($start, $end) = $it->()) { 
     printf "Start: %d - Length: %d\n", $start, $end - $start; 
    } 
} 

Start: 0 - Length: 4 
Start: 7 - Length: 2 
Start: 9 - Length: 3 
Start: 15 - Length: 2 
Start: 19 - Length: 1 
Start: 26 - Length: 5 
0

$line=~ /(HD)/g 

のような構造の結果がリストです。ヒットを踏むにはwhileを使用してください。

+0

OPには開始位置と長さが必要です。 –

0

最後の試合が終了しなかった箇所と一致する場合は、\Gを使用してください。 perldoc perlre氏は述べています(ただし、独自のインストールのバージョンのマニュアル最初に相談してください):

「正規表現の引用で説明したように「\ G」の主張は(「M // G」を使用して) チェーンのグローバルマッチ、 に使用することができます-Lierke オペレータ "がperlopにあります。 スキャナの場合は パターンを使用して と一致させたいときは、 文字列の結果の部分文字列に対して、 "lex"のような文字を書くときに便利な です。 "\ G"が と一致する実際の場所は、左辺値として "pos()"を使用することによっても影響を受けます。 perlfuncの "pos"を参照してください。 の長さが一致するルールは、 が多少変更されていることに注意してください。 の長さの決定時には、 "\ G"の左の内容はに含まれません。私はPerlの専門家ではない

$str = 'ABC'; 
pos($str) = 1; 
while (/.\G/g) { 
    print $&; 
} 
+0

なぜ$&?の無償使用ですか? perldoc perlrerefを参照してください: "$'、$&または$ 'を使用すると、プログラム内のすべての正規表現の使用が遅くなります。遅くなることのない同等の式を見るには、 "@ - "をperlvarに問い合わせてください。 –

+0

おそらく例示的な点を挙げることができます。 Perlreの著者と一緒にそれを取る。 – Anonymous

2

このPEを試してみてくださいrlプログラム

use strict; 
use warnings; 
use feature qw'say'; 

my $file="Sample.txt"; 
open(my $dat, '<', $file) || die("Could not open file!"); 

my @regex = qw(
    HDWFLSFKD 
    HD 
    K 
    DD 
); 

my $sequence; 

while(my $line = <$dat>){ 
    chomp $line; 

    say 'Line: ', $.; 

    # reset the position of variable $line 
    # pos is an lvalue subroutine 
    pos $line = 0; 

    for my $regex (@regex){ 
    $regex = quotemeta $regex; 

    if(scalar $line =~/\G (.*?) ($regex) /xg){ 
     say $regex, ' found at location (', $-[2], '-', $+[2], ')'; 
     if($1){ 
     say " but skipped: \"$1\" at location ($-[1]-$+[1])"; 
     } 
    }else{ 
     say 'Unable to find ', $regex; 

     # end loop 
     last; 
    } 
    } 
} 
+0

これは素晴らしいコード行です。私はperlを愛し始めている! – Omnipresent

+0

必要に応じて、より多くの正規表現を追加することも簡単です。 –

+0

何が起こっているのかを説明するコメントが追加されていれば、それは私を助けてくれるだろう(OPになるかもしれない)。それは素晴らしく見えますが、atleast以来、私はperlにn00bです。私はいくつかの行を取得しません。機能を使用するqw'say '; – Omnipresent

関連する問題