use strict; use warnings; use autodie; use Data::Dumper; my $filename = '11123126_1.dat'; # could take this from command line # ignore blank or # comment lines use constant IGNORE => qr{ ^ \s* (?: [#] .* )? $ }xms; my $rx_identifier = qr{ \w+ }xms; my $rx_toplevel = qr{ $rx_identifier }xms; my $rx_key = qr{ $rx_identifier }xms; my $rx_value = qr{ $rx_identifier }xms; my $toplevel; my %hash; open my $fh, '<', $filename; RECORD: while (my $record = <$fh>) { next RECORD if $record =~ IGNORE; # print Dumper $record; # for debug my $got_toplevel = my ($tl) = $record =~ m{ ^ \s* ($rx_toplevel) \s* : \s* $ }xms; $toplevel = $tl, next RECORD if $got_toplevel; # print Dumper $toplevel; # for debug my $got_key_val = my ($key, $value) = $record =~ m{ ^ \s* ($rx_key) \s* : \s* ($rx_value) \s* $ }xms; # print Dumper $key, $value; # for debug die "no top level seen" unless defined $toplevel; $hash{$toplevel}{$key} = $value, next RECORD if $got_key_val; # no valid record seen. die "bad record '$record'"; } # end while RECORD print Dumper \%hash; close $fh; exit; # subroutines ###################################################### # none for now