0

プログラムで区切りテキスト ファイルの配列をフィルター処理しようとしています。このテキスト ファイルの配列は次のようになります。

YCL049C                   1     511.2465  0 0 MFSK
YCL049C                   2    4422.3098  0 0 YLVTASSLFVALT
YCL049C                   3    1131.5600  0 0 DFYQVSFVK
YCL049C                   4    1911.0213  0 0 SIAPAIVNSSVIFHDVSR
YCL049C                   5     774.4059  0 0 GVAMGNVK
..
.

プログラムのこのセクションのコードは次のとおりです。

my @msfile_filtered;
my $msline;
foreach $msline (@msfile) {

    my ($name, $pnum, $m2c, $charge, $missed, $sequence) = split (" ", $msline);
    if (defined $amino) {

        if ($amino =~ /$sequence/i) {

            push (@msfile_filtered, $msline);

        }

    }
    else {

        push (@msfile_filtered, $msline);

    }

}

$amino は、ユーザーが入力する単なる文字であり、最後のフィールド $sequence に対応します。ユーザーが実際に $amino を入力することは必須ではないため、この配列を複製し、その場合はそのままにしておく必要があります (したがって、else ステートメント)。現時点で @msfile_filtered 配列は空ですが、理由がわかりません。何かアイデアはありますか?

編集:明確にするために、各フィールド間にスペースは1つしかありません。これをnotpad ++からコピーして貼り付けたので、余分なスペースが追加されました。ファイル自体には、フィールド間に 1 つのスペースしかありません。

前もって感謝します!

4

2 に答える 2

3

一致する行を見つけようとする正規表現は逆です。干し草の山から針を見つけるには、 と書く必要がありますが$haystack =~ /needle/、その逆ではありません。

また、ロジックを単純化するために、$aminoisの場合undef、ループを完全にスキップします。私はあなたのコードを次のように書き直します:

if (defined $amino)
{
    foreach $msline (@msfile)
    {
        my ($name, $pnum, $m2c, $charge, $missed, $sequence) = split(" ", $msline);
        push @msfile_filtered, $msline if ($sequence =~ /$amino/i);
    }
} else
{
    @msfile_filtered = @msfile;
}

これをさらに単純化して 1 つのgrepステートメントにすることもできますが、それでは読みにくくなります。このような行の例は次のとおりです。

@msfile_filtered =
    defined $amino
        ? grep { ( split(" ", $_ ) )[5] =~ /$amino/i } @msfile
        : @msfile;
于 2013-11-03T14:28:09.940 に答える
1

分割には複数の空白を使用する必要があり、正規表現変数はその逆です。

最初にデバッグして、分割後に値が正しいことを確認します。

また、次のように正規表現変数を交換する必要があります。

 if ($sequence =~ /$amino/i) {

$amino に $sequence が含まれているかどうかを確認していますが、明らかに含まれていません。

于 2013-11-03T14:31:31.397 に答える