在Perl中,在匹配行之后以迭代方式获取多行?

在Perl中,在匹配行之后以迭代方式获取多行?,perl,hash,pattern-matching,Perl,Hash,Pattern Matching,我想要一个散列结构,每一行以开头是键,下一行直到下一行是该键的值: while (<DATA>) { $line1 = $_; chomp($line1); if ($line1 =~ /^>/) { while (<DATA>) { last if $line1 =~ /^>/; $value .= $_; } $hash{$line1}

我想要一个散列结构,每一行以开头是键,下一行直到下一行是该键的值:

while (<DATA>) {
    $line1 = $_;
    chomp($line1);

    if ($line1 =~ /^>/) {
        while (<DATA>) {
            last if $line1 =~ /^>/;
            $value .= $_;
        }
        $hash{$line1} = $value;
    }
}

foreach my $key(%hash) {
    print "$key :$hash{$key}\n";
}

__DATA__
>label1 
line1\n
line2\n
>label2
line1\n
line2\n
while(){
$line1=$\u1;
chomp($line1);
如果($line1=~/^>/){
而(){
如果$line1=~/^>/,则为最后一个;
$value.=$\ux;
}
$hash{$line1}=$value;
}
}
foreach my$密钥(%hash){
打印“$key:$hash{$key}\n”;
}
__资料__
>标签1
第1行\n
第2行\n
>标签2
第1行\n
第2行\n

我认为使用具有外部作用域的键变量是最简单的方法:

代码 解释 我们将最后看到的散列键保存在变量
$key
中,该变量的作用域位于行迭代循环之外。当循环看到下一个键行时,它将替换
$key
字符串。如果不存在新密钥的数组,perl的机制将在散列中创建一个新的空数组。如果在
$key
下的散列中已有内容,则将在现有行之后添加新行

编辑:如果输入不是以键行开头,则第一个非键行将添加到未标记的键

编辑2:如果希望将标签的行连接起来,可以通过
连接“\n”=>@{$value{$}
轻松完成。如果你想这样做的话,你可以扔掉数组中的东西,使用@perreal的解决方案,这个解决方案非常相似,只是连接了新行

编辑3:是的,自动活体化!:)(谢谢@TLP)

使用警告;
严格使用;
我的%hash;
我的$key;
foreach(){
咀嚼;
如果(/^>(.*)$/){$key=$1;}
else{$hash{$key}.=$\u0}
}
foreach$键(键%hash){
打印“$key:$hash{$key}\n”;
}
__资料__
>标签1
第1行\n
第2行\n
>标签2
第1行\n
第2行\n

您永远不需要使用空数组初始化值。Perl的autovivification将为您处理这个问题。谢谢,我编辑了这个部分。你觉得这样可以吗?请随时提出修改建议。
#!/usr/bin/env perl

use strict;
use warnings;
use feature 'say';

my $key = 'unlabeled';
my %value;

while (defined(my $line = <DATA>)) {
    chomp $line;

    # key line
    if ($line =~ /^>(.*)/) {
        $key = $1;
        next;
    }

    # value line
    push @{$value{$key}}, $line;
}

say "$_: " . join ', ' => @{$value{$_}} for keys %value;

__DATA__
>label1
line1
line2
>label2
line1
line2
label1: line1, line2
label2: line1, line2
use warnings;
use strict;

my %hash;
my $key;

foreach (<DATA>) {
  chomp; 
  if (/^>(.*)$/) { $key = $1; } 
  else           { $hash{$key} .= $_} 
}

foreach $key(keys %hash) {
  print "$key :$hash{$key}\n";
}

__DATA__
>label1 
line1\n
line2\n
>label2
line1\n
line2\n