You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Perl range operator特殊处理:大文件内容提取异常求助

问题描述

我正在解析一个超大文件,无法将其全部读入数组,文件内容示例如下:

文件 input_text.txt:

hello abc
0] Framework table
f1
f2
f3
0] number of entries
randomtext1
0] Test table
t1
t2
t3
0] number of entries
randomtext2
1] Test table
1] Same as framework page table
randomtext3
2] Test table
t4
t5
t6
2] number of entries
randomtext4
3] Test table
t4
t5
t6
3] number of entries
4] Test table
4] Same as framework page table
randomtext5
1] Framework table
f4
f5
f6
1] number of entries
randomtext6
foofoobar

需要提取的表条目预期输出如下:

Here is your framework table:
f1
f2
f3
f4
f5
f6

Here is your test table:
t1
t2
t3
1] Same as framework page table
t4
t5
t6
t4
t5
t6
4] Same as framework page table

我编写了使用Perl range operator的代码,但输出结果不符合预期,不清楚如何正确中断range operator以实现成功解析,代码如下:

$input_log_file = "input_text.txt";
open(LOG_FILE, "$input_log_file") or die("Can't open $input_log_file to read. ");
while (<LOG_FILE>)
{
    if (/Framework table/ .. /number of entries/)
    {
        next if (/Framework table/ || /number of entries/);
        push @framework, $_;
    }
    if (/Test table/ .. /Same as framework page table/)
    {
       next if (/Test table/);
       push @test, $_;
    }
    # if(/Same as framework page table/)
    # {
    #   next;
    # }
    if (/Test table/ .. /number of entries/)
    {
       next if (/Test table/ || /number of entries/);
       push @test, $_;
    }
   
}

close(LOG_FILE);

print "
Here is your framework table:
";
print @framework;
print "
Here is your test table:
";
print @test;
解决方案

原代码的问题在于,处理Test table相关范围时,两个独立的range operator判断会同时触发状态,导致逻辑混乱、内容重复写入。我们可以通过跟踪当前解析状态来替代多range判断,精准控制每个阶段的处理逻辑:

my $input_log_file = "input_text.txt";
open(my $log_fh, "<", $input_log_file) or die("Can't open $input_log_file: $!");

my (@framework, @test);
my $state = 'none'; # 状态:none / parsing_framework / parsing_test

while (my $line = <$log_fh>) {
    # 处理Framework table的起始与结束
    if ($line =~ /Framework table/) {
        $state = 'parsing_framework';
        next;
    }
    if ($line =~ /number of entries/ && $state eq 'parsing_framework') {
        $state = 'none';
        next;
    }

    # 处理Test table的起始与结束
    if ($line =~ /Test table/) {
        $state = 'parsing_test';
        next;
    }
    if ($state eq 'parsing_test') {
        if ($line =~ /number of entries/) {
            $state = 'none';
            next;
        }
        if ($line =~ /Same as framework page table/) {
            push @test, $line;
            $state = 'none';
            next;
        }
    }

    # 根据当前状态收集内容
    push @framework, $line if $state eq 'parsing_framework';
    push @test, $line if $state eq 'parsing_test';
}

close($log_fh);

print "Here is your framework table:\n";
print @framework;
print "\nHere is your test table:\n";
print @test;

代码说明

  1. 状态跟踪:用$state变量明确当前解析阶段,避免多range operator的状态冲突。
  2. 精准匹配结束条件:
    • Framework表以number of entries为结束标记,切换状态且不收集该行;
    • Test表有两种结束标记:number of entries(不收集)和Same as framework page table(收集该行后切换状态)。
  3. 文件句柄优化:使用Perl推荐的词法文件句柄$log_fh,比裸字句柄更安全。
  4. 逐行处理:全程逐行读取、处理,完全适配超大文件的解析需求,不会占用过多内存。

内容的提问来源于stack exchange,提问作者Nee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 11:33:26