0
my $pointer = 0;
foreach (@new1)
{
       my $test = $_;
       foreach (@chk)
       {
               my $check = $_;
               chomp $check;
               delete($new1[$pointer]) if ($test =~ /^$check/i);
       }
       $pointer++;
}

ifステートメントは、@new1配列の多くのエントリに配列要素の先頭に$checkが含まれているという事実と一致することはありません(少なくとも88)。これを試してみると一致しないため、問題の原因がネストされたループであるかどうかはわかりません。

foreach (@chk)
{
        @final = (grep /^$_/, @new1);
}

@finalは空ですが、$_の少なくとも88個の全体が@new1にあることを私は知っています。

このコードはWindowsActivePerl5.14.2を実行しているマシンで作成しましたが、一番上のコードは機能します。次に(@ new1のコピーを使用して)2つを比較し、重複を削除します(5.14.2でも機能します)。ifの一致を否定しようとしましたが、@ new1配列が消去されたようです(ハッシュ比較を行う必要がなかったため)。

Perl5.8.0を使用してLinuxRedHatボックスでこのコードを実行しようとすると、正規表現での変数の一致に苦労しているようです。@ new1にあることがわかっている例でREGEXをハードコーディングすると、一致が機能し、最初のコードでエントリが削除されます(2番目のコードでは@finalに値が挿入されます)。

@chk配列はWebサーバー上のリストファイルであり、@ new1配列は、Webサーバーで2つのログファイルを開き、一方を他方にプッシュすることによって作成されます。

ループの反復ごとに$testと$checkを出力し、値のいずれかが一致するかどうか、およびそれらの一部が一致するかどうかを手動で確認するという問題に直面していました。

それは私を何日も困惑させ、私はタオルを投げ入れて助けを求めなければなりませんでした、何かアイデアはありますか?

4

3 に答える 3

1

user1568538によってテストされたように、解決策は置き換えることでした

chomp $check;

$check =~ s/\r\n//g;

変数からWindowsスタイルの行末を削除します。


chomp入力レコードセパレータの内容を引数の末尾から削除するため$/、その値を変更することもできます。

my $pointer = 0;
foreach (@new1)
{
   my $test = $_;
   foreach (@chk)
   {
       local $/="\r\n";
       my $check = $_;
       chomp $check;
       delete($new1[$pointer]) if ($test =~ /^$_/i);
   }
   $pointer++;
}

ただし、他の操作(ファイルハンドルからの読み取りなど)にも影響するため、安全かどうか確信が持てない限り$/、変更を避けるのがおそらく最も安全です。ここでは、発生するループ$/への変更を制限します。foreachchomp

于 2012-08-02T13:11:31.923 に答える
1

入力データがどのように見えるかわからない場合、次を使用\Qすると役立つ場合があります。

if ($test =~ /^\Q$check/i);

引用メタを参照してください。

于 2012-08-01T12:54:37.770 に答える
1

あなたが何をしようとしているのかは明らかではありません。ただし、一致しない要素のみを取得しようとしている場合や、その逆の場合があります。必要に応じて以下のコードを調整します

#!/usr/bin/perl
use strict; use warnings;

my @item  = qw(...); # your @new?
my @check = qw(...); # your @chk?
my @match;
my @nomatch;

ITEM:
foreach my $item (@item) {

   CHECK:
   foreach my $check (@check) {
      # uncomment this if $check should not be interpreted as a pattern,
      # but as literal characters:
      # $item = '\Q' . $item;
      if ($item =~ /^$check/) {
         push @match, $item;
         next ITEM; # there was a match, so this $item is burnt
          # we don't need to test against other $checks.
      }
   }

   # there was no match, so lets store it:
   push @nomatch, $item.
}

print "matched $_\n" for @matched;
print "didn't match $_" for @nomatch;

あなたのコードはやや読みにくいです。これは何ですか?

foreach (@chk) {
   @final = (grep /^$_/, @new1);
}

する: それはほぼ同等です

my @final = ();
foreach my $check (@chk) {
   @final = grep /^$check/, @new1;
}

これはと同等です

my @final = ();
foreach my $check (@chk) {
   # @final = grep /^$check/, @new1;
   @final = ();
   foreach (@new) {
      if (/^$check/) {
         push @final, $_;
         last;
      }
   }
}

したがって、 @final 配列がリセットされ、空になる可能性があります。

于 2012-08-01T14:22:16.390 に答える