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

Perl脚本无法提取含多个成员的完整Group文本块求助

问题描述

我需要从文本文件中提取符合特定格式的信息块用于后续处理,目标块格式如下:

Group NAME

Description DESCRIPTION

Group member MEMBER

所有Group都包含成员,Description是可选字段,成员数量可以是一个或多个,成员名可以是名称或数字。

我写了下面的Perl脚本:

#!/usr/bin/perl

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

my $path="input.txt";

open my $fh, "<", $path or die "Can't open $path: $!";
#local $/;
my $accumulated_text = '';
while (my $line = <$fh>)
{
    $accumulated_text .= $line;
    #Match against accumulated text
    if ($accumulated_text =~ /group.*\s*(description.*\s*)?\s*(member.*\s*)+/)
 {
        say $&;
        $accumulated_text = '';
    }
}
close $fh;

但这个脚本只能提取一个Group成员,没法提取全部成员。试过用{1,}替代+结果一样,用{2,}这类则只提取指定数量的成员。请问怎么修改才能提取包含所有成员的完整Group块?期望输出是包含所有成员的完整Group信息块。

解决方案

问题出在正则匹配逻辑和文本累积的终止条件上:当前正则会在匹配到第一个member行后就触发匹配,不会等待后续成员行;另外(member.*\s*)+虽然理论上支持多次匹配,但因为没有明确的块终止标记,导致匹配提前结束。可以从以下两个方向修改:

1. 按段落读取+精准匹配(适用于Group块用空白行分隔的场景)

如果你的输入文件中,每个Group块之间用空白行分隔,可以直接用Perl的段落模式读取,再匹配完整块:

#!/usr/bin/perl

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

my $path = "input.txt";

open my $fh, "<", $path or die "Can't open $path: $!";

local $/ = ""; # 开启段落模式,按空白行分隔读取内容块
while (my $block = <$fh>) {
    # 匹配包含Group开头、可选Description、至少一个成员的完整块
    if ($block =~ /^Group\s+\S+.*?(?:Description\s+.*?)?(?:Group member\s+.+)+/is) {
        print $&;
        print "\n" unless $& =~ /\n\z/; # 保证块末尾有换行,避免格式混乱
    }
}

close $fh;

2. 基于下一个Group作为终止标记(适用于无空白行分隔的场景)

如果Group块之间没有空白行,而是以下一个Group行作为结束标记,可以用正向预查来限定匹配范围:

#!/usr/bin/perl

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

my $path = "input.txt";

open my $fh, "<", $path or die "Can't open $path: $!";

local $/; # 一次性读取整个文件
my $content = <$fh>;

# 匹配所有完整的Group块,直到下一个Group或文件末尾
while ($content =~ /Group\s+\S+.*?(?=Group|\z)/isg) {
    my $group_block = $&;
    # 过滤掉没有成员的无效块(题目要求所有Group都有成员)
    if ($group_block =~ /Group member\s+.+/s) {
        print $group_block;
        print "\n" unless $group_block =~ /\n\z/;
    }
}

close $fh;

关键修改说明

  • 段落模式local $/ = "":自动将空白行分隔的内容作为独立块读取,刚好对应单个Group的范围。
  • 正则修饰符/is:i忽略大小写(适配输入中Group、Description等关键词大小写不固定的情况);s让.匹配换行符,确保跨多行匹配完整块。
  • 正向预查(?=Group|\z):指定匹配的终止边界,要么是下一个Group开头,要么是文件末尾,保证捕获完整的当前Group块。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 04:08:11