Perl 自动化散列填充和键名

sfr*_*sfr 2 perl

我有许多错误字符串。我正在将它们与我已有的模式相匹配。如果它们完全相同,我希望它们属于完全相同的错误故障。如果它们匹配模式但与哈希中的先前字符串有一些不同,我想给它相同的错误名称,但附加不同的数字。

这是一个示例输入文件:

there are 5 syntax issues with semicolon
there are 11 syntax issues with semicolon
the file contains 5 formatting issues
there are 1 syntax issues with semicolon
check script for formatting issues
2 syntax issues have been found
the file contains 1 formatting issues
6 syntax issues have been found
Run Code Online (Sandbox Code Playgroud)
use warnings;
use strict;

my %errors;
my $file = "listoferrormessages.txt"

open my $fh,'<',$file or die "Could not open $file: $!";

while(my $line = <$fh>){

if( $line =~ /syntax/){

    if ($line =~ /there are \d syntax issues with semicolon/){
       #if line matching format exists in hash values, continue
       #if not, create a hash key called syntax_# where # increments one from the last key with the error name. 
        $errors{errorname} = $line;
}

    elsif ($line =~ /\d syntax issues have been found/){
       #same as above
       $errors(errorname} = $line;
}

elsif ($line =~ /format/){
#same as above
}

}
close $fh;

Run Code Online (Sandbox Code Playgroud)

我希望我的哈希看起来像:

$VAR1 = {
          'syntax_1' => 
                     'there are 5 syntax issues with semicolon',
          'syntax_2' => 
                     '2 syntax issues have been found',
          'format_1' => 
                     'the file contains 5 formatting issues',
          'format_2' => 
                     'check script for formatting issues'
        };
Run Code Online (Sandbox Code Playgroud)

任何关于这方面的指导都会非常有帮助。我想补充的还有很多,但我对如何开始这样做感到非常困惑。这甚至可以做到吗?

zdi*_*dim 5

这完成了所要求的工作,剩下的问题是可能的错误类型。

有一个辅助数据结构 ( %seen_error_type) 以避免在每一行中搜索值,以检查是否已看到该错误类型;有了这个哈希,它只是一个查找。

use warnings;
use strict;
use feature qw(say);

use Data::Dump qw(dd);  # to show complex data structures

my $file = shift // die "Usage: $0 file\n";  #/
open my $fh, '<', $file  or die "Can't open $file: $!";

my (%error, %seen_error_type, $cnt_syntax, $cnt_format);

LINE:
while (my $line = <$fh>) { 
    chomp $line;

    my $error_type = $line =~ s/[0-9]+/N/r;  # extract error type

    next LINE if exists $seen_error_type{$error_type};
    $seen_error_type{$error_type} = 1;

    if ($line =~ /syntax/) {
        ++$cnt_syntax;
        $error{ "syntax_$cnt_syntax" } = $line;
    }
    elsif ($line =~ /format/) {
        ++$cnt_format;
        $error{ "format_$cnt_format" } = $line;
    }   
    else { }  # specify how to handle unexpected error types
}       
    
dd \%error;
Run Code Online (Sandbox Code Playgroud)

首先从一行构建错误“类型”,将数字替换为N; 这仅遵循 OP 示例,因为没有给出如何对这些错误消息进行分类的规则。如果这确实是全部,那很好。但我希望对预期的各种错误有更复杂的标准。

改进这一点的关键需要是阐明预期什么“错误类型”(错误消息的结构)的规则。

简单地将意外的模式添加到我们的错误类型的簿记哈希中是没有意义的,除非我们有一些关于如何从一行中提取模式的规则。否则,每一行可能的文本最终都可能成为其自身的关键,这将破坏对它们进行分类的整个练习的目的。

使用给定的输入文件,上面的打印

{
  format_1 => "文件包含 5 个格式问题",
  format_2 => "检查脚本的格式问题",
  语法_1 =>“分号有5个语法问题”,
  语法_2 => "已发现 2 个语法问题",
}

(我使用的Data::Dump模块可能需要安装。核心选项是Data::Dumper


另外要注意,在意见中提出:我不明白为什么要添加密钥为每个新行,而不是将每个预期误差型线到数组引用一个合适的键(syntaxformat,等)。

如果没有具体原因,那么我宁愿建议类似

my (%error, %seen_error_type);

LINE:
while (my $line = <$fh>) { 
    chomp $line;

    my $error_type = $line =~ s/[0-9]+/N/r;  # extract error type

    next LINE if exists $seen_error_type{$error_type};
    $seen_error_type{$error_type} = 1;

    if ($line =~ /syntax/) {
        push @{$error{syntax}}, $line;
    }   
    elsif ($line =~ /format/) { 
        push @{$error{format}}, $line;
    }
    else { }  # specify how to handle unexpected error types
}

dd \%error;
Run Code Online (Sandbox Code Playgroud)

现在我们只有一个 key 的数组引用syntax,另一个 key 的引用format

这打印

{
  格式 => [
              “该文件包含 5 个格式问题”,
              “检查脚本的格式问题”,
            ],
  语法 => [
              “分号有 5 个语法问题”,
              "已发现 2 个语法问题",
            ],
}