0

我有一个如下输入文件:

start
f1="apple"
f2="banana"
f3="berry"
end
start
f1="guava"
f2="banana"
f3="berry"
end
start
f1="apple"
f2="cucumber"
f3="orance"
end

我打算创建一个值作为数组的哈希。

所有标签都将位于一个临时数组中,并且在标签之间有一个字段f1,其值将是哈希的键。

从开始到结束,它将存储在临时数组中,一旦到达结束,数组作为哈希值被推送,键为最新字符串之后的值f1=

我已经编写了以下代码,但它不起作用。

有人可以在这里提出任何更正吗?

#!/usr/bin/perl -w

use strict;

use Data::Dumper;

open( FILE, "<", "temp2" );

my %FILEDATA;
my @tmp   = ();
my $fruit = "";

while ( <FILE> ) {

    chomp( $_ );
    push @tmp, $_;

    my @linefields = split( '=', $_ );

    if ( $linefields[0] =~ /f1/ ) {
        $fruit = $linefields[1];
    }

    if ( $_ =~ /end/ ) {

        if ( $fruit eq "apple" ) {

            if ( exists $FILEDATA{"apple"} ) {
                push( @{ $FILEDATA{"apple"} }, @tmp );
            }
            else {
                $FILEDATA{"apple"} = @tmp;
            }
        }
        elsif ( $fruit eq "guava" ) {

            if ( exists $FILEDATA{"guava"} ) {
                push( @{ $FILEDATA{"guava"} }, @tmp );
            }
            else {
                $FILEDATA{"guava"} = @tmp;
            }

        }

        undef @tmp;
    }
}

print Dumper( \%FILEDATA );
4

2 回答 2

1

我假设这是家庭作业

这里有一些指导方针

  • $_是许多 Perl 运算符的默认参数。特别是,chomp( $_ )可以写成chompsplit( '=', $_ )应该是split /=/if ( $_ =~ /end/ ) { ... }可以是if ( /end/ )

  • 无需测试 的值$fruit。如果它的值是您想要的键,那么您应该使用$FILEDATA{$fruit}

  • $FILEDATA{"apple"} = @tmp设置$FILEDATA{"apple"}为 中的元素@tmp。您需要将其设置为对数组的引用,使用$FILEDATA{"apple"} = \@tmp

  • 使用前无需检查哈希或数组元素是否存在push。如果你只是push @{ $FILEDATA{apple} }, 'ff'那么将创建数组

  • if ( $linefields[0] =~ /f1/ )测试是否$linefields[0] 包含字符串f1。测试你想要的平等if ( $linefields[0] eq 'f1' )

  • undef @data您不应该使用or清空数组或散列@data = undef。正确的方法是@data = ()。要清空标量,请使用$val = undef

这是您的代码的外观

#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

open FILE, "<", "fruit.txt";

my %data;
my @tmp;
my $fruit;

while ( <FILE> ) {

    chomp;
    push @tmp, $_;

    my @fields = split /=/;

    if ( $fields[0] eq 'f1' ) {
        $fruit = $fields[1];
    }

    if ( /end/ ) {
        push @{ $data{$fruit} }, [ @tmp ];
        @tmp = ();
    }
}

print Dumper( \%data );

输出

$VAR1 = {
          '"guava"' => [
                         [
                           'start',
                           'f1="guava"',
                           'f2="banana"',
                           'f3="berry"',
                           'end'
                         ]
                       ],
          '"apple"' => [
                         [
                           'start',
                           'f1="apple"',
                           'f2="banana"',
                           'f3="berry"',
                           'end'
                         ],
                         [
                           'start',
                           'f1="apple"',
                           'f2="cucumber"',
                           'f3="orance"',
                           'end'
                         ]
                       ]
        };

这就是我要写的方式

#!/usr/bin/perl

use strict;
use warnings;
use autodie;

use Data::Dumper;

my $file = 'fruit.txt';

open my $fh, '<', $file
    or die qq{Unable to open "$file": $!};

my ( %data, @block, $fruit );

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

    chomp $line;

    push @block, $line if @block or $line eq 'start';

    $fruit = $1 if $line =~ /^f1="(\w+)"/;

    if ( $line eq 'end' ) {
        push @{ $data{$fruit} }, [ @block ];
        @block = ();
        $fruit = undef;
    }
}

print Dumper \%data;

请注意,您不应使用undef @dataor清空数组或散列@data = undef。正确的方法是@data = ()

于 2017-05-31T17:33:05.253 回答
-1

试试这个代码

my $file = 'fruits.txt';
my %hash;


open (my $fh, '<', $file) or die "Could not open $!";
while(my $line = <$fh>) {
  next if $line =~ /start/;
  next if $line =~ /end/;

  if ($line =~ /f1/) {
     my ($key, $val) = split /=/, $line;
     push @{$hash{$key}}, $val;
   }

   if ($line =~ /f2/) {
    my ($key, $val) = split /=/, $line;
    push @{$hash{$key}}, $val;
   }

   if ($line =~ /f3/) {
    my ($key, $val) = split /=/, $line;
    push @{$hash{$key}}, $val;
   }

}

print Dumper(\%hash);
于 2017-05-31T17:28:08.333 回答