while (<FILE>){ @Input = <FILE>; }
これはあまり意味がありません。 「FILEからレコードを読み取ることができますが、FILEのすべてのデータを@Input
に読み込みます。
my @Input = <FILE>;
if (@Input =~ /header2/){
これはあまりにも非常に奇妙です:私はあなたが実際にしたいことだけだと思います。バインディング演算子(=~
)は、スカラーオペランドを必要とするため、スカラーコンテキストの両方のオペランドを評価します。つまり、@Input
は、@Input
の要素の数として評価されます。これは整数で、 "header2"とは決して一致しません。
いくつかのアプローチがあります。まず、正規表現のアプローチ。
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
my $file = 'file';
open my $fh, '<', $file or die $!;
my $data = join '', <$fh>;
if ($data =~ /header2.+var3 (.+?)\n/s) {
say $1;
} else {
say 'Not found';
}
これの鍵は、m//
オペレーターに/s
です。それがなければ、正規表現の2つの点は改行にマッチしません。
もう1つのアプローチは、行単位のパーサーのほうが多くなります。
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
my $file = 'file';
open my $fh, '<', $file or die $!;
my $section = '';
while (<$fh>) {
chomp;
# if the line all word characters,
# then we've got a section header.
if ($_ !~ /\W/) {
$section = $_;
next;
}
my ($key, $val) = split;
if ($section eq 'header2' and $key eq 'var3') {
say $val;
last;
}
}
ファイルを一度に1行ずつ読み込み、セクションヘッダーを書き留めます。データラインについては、空白を分割し、正しいセクションにあるかどうかを確認し、正しいキーを持っているかどうかを確認します。
どちらの場合も、私はファイルを開くためのより標準的なアプローチ(字句ファイルハンドル、3-arg open()
、or die $!
)を使用するように切り替えました。
「*でも、マルチライン解析を適切に処理することはできないと思います。」 - 実際のコードをさらに表示すると、その問題は解決できる可能性がありますか?おそらく、複雑な正規表現を使わなくても簡単な解決法があります。 "*今はすぐにファイルを解析することを考えていますが、これまで成功していませんでした... *" - これがどのように機能しないのかを明確にすることはできますか?そのスニペットにはいくつかの問題がありますが、それらはすべてあなたのタイトル(lookbehindを持つregexes)の問題とは無関係です。貴重な情報はhttps://perlmaven.com/slurpを参照してください。 – amon