Один совет, прежде чем я продолжу:
Документируйте свой код
В вашем коде есть несколько логических ошибок, которые, я думаю, вы бы распознали, если бы написаливниз, что вы думали, что каждая строка должна была сделать.Сначала запишите алгоритм, который вы хотели бы реализовать, а затем задокументируйте, как каждый шаг в коде реализует шаг в алгоритме.В конце вы сможете увидеть, что вы пропустили, или какая часть не работает.
Вот ошибки, которые я вижу
- Вы не игнорируете строки, которыеВы не должны анализировать.Например, вы берете строки '}' и '{'.
- На самом деле вы не сохраняете название фрукта.Вы берете его, но сразу же начинаете следующий цикл, не сохраняя его.
- Вы не отслеживаете каждую структуру.Вам нужно создать новую структуру для каждого фрукта.
- Вы действительно хотите сохранить двойные кавычки в значениях?
Другие вещи, о которых нужно беспокоиться:
- Гарантируется ли, что список атрибутов находится в таком порядке?Например, может ли
Name
прийти последним?
Вот некоторый код, который делает то, что я думаю, вы хотите.
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my %hash_table;
my $name;
my @fruit;
my $file = '/tmp/fruitdir/fruit1.txt';
open my $fh, "<", $file or die "Can't open $file: $!";
while (<$fh>) {
chomp;
# save hash table if there's a close bracket, but
# only if it has been filled
if ( /^\s*}\s*$/ ) {
next unless keys %hash_table;
# save COPY of hash table
push @fruit, { %hash_table };
# clear it out for the next iteration
%hash_table = ();
}
# only parse lines that start with Name or fruit
next unless
my ( $key, $value ) =
/^
# skip any leading spaces
\s*
# parse a line beginning with Name or fruitXXXXX
(
Name
|
fruit[^\s]+
)
# need space between key and value
\s+
# everything that follows is a value. clean up
# double quotes in post processing
(.*)
/x;
# remove double quotes
$value =~ s/"//g;
if ( $key eq 'Name' ) {
$name = $value;
}
else {
$key = "${name}.${key}";
}
$hash_table{$key} = $value;
}
print Dumper \@fruit;
и вот вывод:
$VAR1 = [
{
'fruit 1.fruitValue' => '6',
'fruit 1.fruitName' => 'apple.fru',
'Name' => 'fruit 1',
'fruit 1.fruitCount' => '5',
'fruit 1.fruitId' => '0'
},
{
'fruit 2.fruitName' => 'orange.fru',
'fruit 2.fruitId' => '1',
'fruit 2.fruitCount' => '10',
'fruit 2.fruitValue' => '20',
'Name' => 'fruit 2'
}
];