gpt4 book ai didi

regex - 如何从 Perl 的文件中读取自定义模式?

转载 作者:行者123 更新时间:2023-12-01 09:40:25 25 4
gpt4 key购买 nike

提前祝大家新年快乐。

我有一个错误日志文件,其中包含模式参数、结果和 stderr 中的内容(stderr 可以是多行)。

$cat error_log

<parameter>:test_tot_count
<result>:1
<stderr>:Expected "test_tot_count=2" and the actual value is 3
test_tot_count = 3
<parameter>:test_one_count
<result>:0
<stderr>:Expected "test_one_count=2" and the actual value is 0
test_one_count = 0
<parameter>:test_two_count
<result>:4
<stderr>:Expected "test_two_count=2" and the actual value is 4
test_two_count = 4
...

我需要在 Perl 中编写一个函数来将每个参数、结果和 stderr 存储在一个数组或哈希表中。

这是我们自己内部定义的结构。我这样写了 Perl 函数。有没有更好的方法来使用正则表达式本身?

my $err_msg = "";
while (<ERR_LOG>)
{
if (/<parameter>:/)
{
s/<parameter>://;
push @parameter, $_;
}
elsif (/<result>:/)
{
s/<result>://;
push @result, $_;
}
elsif (/<stderr>:/)
{
if (length($err_msg) > 0)
{
push @stderr, $err_msg;
}
s/<stderr>://;
$err_msg = $_;
}
else
{
$err_msg .= $_;
}
}
if (length($err_msg) > 0)
{
push @stderr, $err_msg;
}

最佳答案

如果您使用的是 Perl 5.10,您可以使用 given/when 结构做一些与现在非常相似但布局更好的事情:

use 5.010;

while (<ERR_LOG>) {
chomp;
given ($_) {
when ( m{^<parameter>: (.*)}x ) { push @parameter, $1 }
when ( m{^<result>: (.*)}x ) { push @result, $1 }
when ( m{^<stderr>: (.*)}x ) { push @stderr, $1 }
default { $stderr[-1] .= "\n$_" }
}
}

值得注意的是,对于这里的默认情况,我没有保留单独的 $err_msg 变量,而是在看到 stderr 标记时直接推送到 @stderr ,如果我看到续行,则附加到 @stderr 数组的最后一项。当我看到续行时,我会添加一个换行符,因为我假设您希望保留它们。

尽管上面的代码看起来很优雅,但我真的不太喜欢保留三个独立的数组,因为如果事情不同步,它可能会让你头疼,因为如果你将来想要添加更多字段,最终会出现很多需要跟踪的变量。我建议将每条记录存储在一个哈希中,然后保留一个记录数组:

use 5.010;

my @records;

my $prev_key;

while (<ERR_LOG>) {
chomp;
given ($_) {
when ( m{^<parameter> }x ) { push(@records, {}); continue; }
when ( m{^<(\w+)>: (.*)}x ) { $records[-1]{$1} = $2; $prev_key = $1; }
default { $records[-1]{$prev_key} .= "\n$_"; }
}
}

在这里,当我们看到一个字段时,我们将一条新记录推送到数组中,每当我们看到键/值对时向我们的哈希添加一个条目,如果我们看到续行,则附加到我们添加的最后一个字段. @records 的最终结果如下所示:

(
{
parameter => 'test_one_count',
result => 0,
stderr => qq{Expected "test_one_count=2" and the actual value is 0\ntest_one_count=0},
},
{
parameter => 'test_two_count',
result => 4,
stderr => qq{Expected "test_two_count=2" and the actual value is 4\ntest_two_count=4},
}
)

现在您可以只传递一个包含所有记录的数据结构,并且您可以在将来添加更多字段(甚至是多行字段)并且它们将得到正确处理。

如果您没有使用 Perl 5.10,那么这可能是升级的好借口。如果没有,您可以将 given/when 结构转换为更传统的 if/elsif/else 结构,但它们在转换中失去了很多美感。

保罗

关于regex - 如何从 Perl 的文件中读取自定义模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/402763/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com