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

if 语句永远不会匹配 @new1 数组中的许多条目在数组元素(至少 88 个)的开头包含 $check 的事实。我不确定是嵌套循环导致了问题,因为如果我尝试这样做,它也无法匹配:

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

@final 是空的,但我知道 $_ 至少有 88 个整数在 @new1 中。

我在运行 Windows ActivePerl 5.14.2 的机器上编写了这段代码,并且上面的代码有效。然后我(使用@new1 的副本)比较两者并删除任何重复项(也适用于 5.14.2)。我确实尝试否定 if 匹配,但这似乎消除了 @new1 数组(因此我不需要进行哈希比较)。

当我尝试在带有 Perl 5.8.0 的 Linux RedHat 机器上运行此代码时,它似乎很难与 REGEX 中的变量匹配。如果我用我知道在@new1 中的示例对 REGEX 进行硬编码,则匹配有效,并且在第一个代码中,条目被删除(在第二个代码中,@final 中插入了一个值)。

@chk 数组是 Web 服务器上的列表文件,@new1 数组是通过在 Web 服务器上打开两个日志文件然后将一个推入另一个来创建的。

我什至在每次循环迭代中打印出 $test 和 $check 并手动检查是否有任何值匹配并且其中一些匹配。

这让我困惑了好几天,我不得不把毛巾扔进去寻求帮助,有什么想法吗?

4

3 回答 3

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);
}

do: 大致相当于

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 回答
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++;
}

但是,由于$/也会影响其他操作(例如从文件句柄中读取),因此避免更改可能是最安全的,$/除非您确定它是否安全。在这里,我将更改限制在发生的foreach循环中chomp

于 2012-08-02T13:11:31.923 回答