4

ファイルを開いて解析するコードがあります。このテキストドキュメントは冗長な構造であり、複数のエントリがあります。ループ内を覗いて、新しいエントリがあるかどうかを確認する必要があります。新しいエントリがある場合は、プログラムが抽出するすべてのデータを解析できるようになります。これまでの実装を最初に示しましょう

use strict;
my $doc = open(my $fileHandler, "<", "test.txt");

while(my $line = <$fileHandler>) {
    ## right here I want to look at the next line to see if 
    ## $line =~ m/>/ where > denotes a new entry
}
4

2 に答える 2

9

自分で反復を処理してみてください。

my $line = <$fileHandler>;
while(1) { # keep looping until I say so
    my $nextLine = <$fileHandler>;

    if ($line =~ m/>/ || !defined $nextLine) {
        ### Do the stuff
    }
    ### Do any other stuff;

    last unless defined $nextLine;
    $line = $nextLine;
}

ファイルの最後に到達したときに持っているものも処理することを想定して、ifステートメントに追加のチェックを追加しました。

または、friedoが提案しているように、ファイルがメモリに収まる場合は、すべてを一度に配列にロードできます。

my @lines = <$fileHandler>;
for (my $i = 0; $i <= $#lines; $i++) {
    if ($i == $#lines || $lines[$i+1] =~ />/) {
        ### Do the stuff
    }
}

これは、ファイルの任意の行に任意の順序でアクセスできるという点でより柔軟性がありますが、前述のように、ファイルはメモリに収まるように十分に小さくする必要があります。

于 2013-01-15T18:35:31.840 に答える
5

これらの問題を処理する良い方法はTie::File、を使用することです。これにより、ファイルを実際にメモリにロードするというパフォーマンスの低下なしに、ファイルを配列のように扱うことができます。perlv5.7.3以降のコアモジュールでもあります。

use Tie::File;
tie my @file, 'Tie::File', "test.txt" or die $!;

for my $linenr (0 .. $#file) {             # loop over line numbers
    if ($file[$linenr] =~ /foo/) {         # this is the current line
        if ($file[$linenr + 1] =~ /^>/ &&  # this is the next line
            $linenr <= $#file) {           # don't go past end of file
             # do stuff
        }
    }
}
untie @file;   # all done
于 2013-01-15T19:10:17.163 に答える