0

我找到了可以在 perlmonks.org ( http://www.perlmonks.org/?node_id=870806 ) 上使用的东西,但我无法让它工作。

我可以毫无问题地读取文件并构建一个数组。然后,我想将数组的每个索引(每个正则表达式)与文件的每一行进行比较,打印出匹配行之前的行和匹配行之后的行。

我的代码:

# List of regex's.  If this file doesn't exist, we can't continue
open ( $fh, "<", $DEF_FILE ) || die ("Can't open regex file: $DEF_FILE");
while (<$fh>) {
    chomp;
    push (@bad_strings, $_);
}
close $fh || die "Cannot close regex file: $DEF_FILE: $!";

$file = '/tmp/mydirectory/myfile.txt';
eval { open ( $fh, "<", $file ); };
if ($@) {
      # If there was an error opening the file, just move on
      print "Error opening file: $file.\n";
} else {
      # If no error, process the file
      foreach $bad_string (@bad_strings) {
              $this_line = "";
              $do_next = 0;
              seek($fh, 0, 0); # move pointer to 0 each time through
              while(<$fh>) {
                      $last_line = $this_line;
                      $this_line = $_;
                      my $rege = eval "sub{ \$_[0] =~ $bad_string }"; # Real-time regex
                      if ($rege->( $this_line )) {                    # Line 82
                             print $last_line unless $do_next;
                             print $this_line;
                             $do_next = 1;
                      } else {
                             print $this_line if $do_next;
                             $last_line = "";
                             $do_next = 0;
                      }
              }
      }
}  # End "if error opening file" check

当我在文件中每行只有一个字符串并执行简单的测试if ($this_line =~ /$string_to_search_for/i )时,这是可行的,但是当我在文件中切换到正则表达式和“实时”eval语句时,我现在得到Can't use string ("") as a subroutine ref while "strict refs" in use at scrub_file.pl line 82第 82 行是if ($rege->($this_line)) {.

在该错误消息之前,我收到:Use of uninitialized value in subroutine entry at scrub_hhsysdump_file.pl line 82, <$fh> 我对该错误消息有一些了解,但到目前为止似乎无法让 perl 引擎对我的代码感到满意。

perl 还是新手,总是在寻找指针。提前致谢。

4

1 回答 1

2

我看不出这些eval陈述的原因——他们似乎所做的只是使代码变得更加复杂和难以调试。

但是$rege是 undef 因为eval "sub{ \$_[0] =~ $bad_string }"字符串有语法错误而无法正常工作。我不知道 中的内容$DEF_FILE,但除非它具有正确分隔的正则表达式,否则您需要在eval字符串中添加分隔符。

my $rege = eval "sub{ \$_[0] =~ /$bad_string/ }"

可能有效,但/\Q$bad_string/如果其中的字符串$DEF_FILE包含正则表达式元字符并且您希望它们被视为文字字符,则您可能需要。

我建议您的程序的这个版本似乎可以满足您的需要,而无需大惊小怪eval

use strict;
use warnings;

use Fcntl ':seek';

my $DEF_FILE = 'myfile';

my @bad_strings = do {
  open my $fh, '<', $DEF_FILE or die qq(Can't open regex file "$DEF_FILE": $!);
  <$fh>;
};
chomp @bad_strings;

my $file = '/tmp/mydirectory/myfile.txt';

open my $fh, '<', $file or die qq(Unable to open "$file" for input: $!);

for my $bad_string (@bad_strings) {

  my $regex = qr/$bad_string/;

  my ($last_line, $this_line, $do_next) = ('', '', 0);

  seek $fh, 0, SEEK_SET;

  while (<$fh>) {

    ($last_line, $this_line) = ($this_line, $_);

    if ($this_line =~ $regex) {
      print $last_line unless $do_next;
      print $this_line;
      $do_next = 1;
    }
    else {
      print $this_line if $do_next;
      $do_next = 0;
    }
  }
}
于 2013-01-10T21:33:40.310 回答