問題は非常に単純です。プログラムで$1
、$2
、および$3
を使用していますが、それらを使用するまでにそれらの価値を失っています。これらはグローバル シンボルであり、正規表現演算子を使用するたびに置き換えられます。最初の正規表現の一致後、それらを別の変数に保存するだけです。
$first = $1;
$second = $2;
$third = $3;
正規表現にも注意が必要です。あなたの正規表現は機能しますが、非常に狭いです。ファイルにタブがあったのを初めて見逃しました。私\s+
はあらゆる種類の空白に使用するのが好きです。これにより、複数のタブまたはスペース、または異なるものの組み合わせがカバーされます。
また、最新の Perlを学ぶことを強くお勧めします。プログラムで次の 2 行を使用していれば、すぐに問題を解決できたはずです。
use strict;
use warnings;
は、またはstrict
を介して変数を定義したことを確認します。これにより、ある場所と別の場所を言って、 に保存した値に何が起こったのか疑問に思うことがなくなります。my
our
$Foo
$foo
$foo
はwarnings
すぐにそれを強調表示し、2 番目の正規表現の一致を行うときに値が$1
ありません。$2
のせいで、require
を使うと変数宣言がちょっとベタベタしますstrict
。my
変数は、スコープが限定された厳密にローカルな変数です。そのため、99% の確率で使用されています。
変数は、宣言されたmy
スコープ内にのみ存在します。たとえば、ループ内で変数を宣言すると、ループの外には存在しません。
if ($a > $b) {
my $highest = $a;
}
else {
my $highest = $b;
}
print "The highest value is $highest\n";
$highest
if ステートメント内で定義されているため、これは機能しません。$highest
機能させるには、ステートメントの外側で宣言する必要があります。
my $highest;
if ($a > $b) {
$highest = $a;
}
else {
$highest = $b;
}
print "The highest value is $highest\n";
宣言された変数は、パッケージour
全体でグローバルに使用できます。ループ内、if ステートメント内など、どこでも定義でき、後で使用できるようになります。
パッケージは単なる名前空間です。別の方法で宣言しない限り、あなたは常にmain
パッケージの中にいます。モジュール変数がコード内の変数に影響を与えないようにするのに役立ちます。このようにして、含まれているモジュールは変数を使用でき、相互に干渉することなく$foo
変数を使用できます。$foo
私がこれに踏み込まなければならなかった理由は、あなたのrequire
. 変数はそのmy
スコープ内でのみ使用できます。つまり、for ループ、if ステートメント、またはファイル全体です。最後の 1 つに注意してください:ファイル全体. これは、そうするとmy %h1
、ファイルの外には存在しないことを意味します。したがって、 . で宣言する必要がありour
ます。
また、 を使用する場合strict
は、かなり厳格です。宣言されていない変数を検出すると、コンパイル時エラーが発生します。したがって、メインプログラム内で宣言する必要が%h1
あるため、コンパイラーはそれを認識します。
say
から得たステートメントも使用しuse feature qw(say);
ます。print
常にNL文字を出力する以外は似ています。たいしたことではないように思えますが、多くの状況ではそれほど面倒ではありません。
ファイルを開くには、ファイル ハンドルだけでなく、宣言されたスカラーを使用することを強くお勧めします。ファイル ハンドルはグローバルであり、問題を引き起こす可能性があります。さらに、サブルーチンでファイル ハンドルを使用するのは困難です。また、3 部構成のオープン ステートメントを使用することをお勧めします。>
これにより、ファイル名がまたはで始まる場合の問題を回避できます|
。
これは、もう少し現代的な Perl 風に書き直されたプログラムです。標準のアルゴリズムを維持しましたが、新しいプラグマを追加し、それを ing する%h1
前に宣言し、より標準的な を使用しました。そうでなければ、それはあなたが持っていたものとほとんど同じです。require
open
#! /usr/bin/env perl
#
use strict;
use warnings;
use feature qw(say);
our %h1;
require "hash.pl";
open ( my $input_fh, "<", "input.txt" )
or die "can't open file: $! \n";
foreach my $amp ( <$input_fh> ) {
chomp $amp;
if ( $amp =~ /(\d+)\s+(\d+)\s+(\d+)/ ) {
# Got to save the $1, $2, and $3 for later
my $first = $1;
my $second = $2;
my $third = $3;
foreach my $key ( keys %h1 ) {
foreach my $tmp1 ( @{$h1{$key}} ) {
if ($tmp1 =~ /($first\s+$second|$second\s+$first)/ ) {
say qq("$key": "$third");
}
}
}
}
}
close $input_fh;