use warnings; use strict; use Data::Dump::Streamer; my %lookup; my $main; my $action; my $text; while () { chomp; if (m/^Main\b/ .. m/^End\b/) { # Process Main/End blocks next if ! /Name = (\w+)/; $main = $1; } elsif (m/^Sub\b/ .. m/^End\b/) { # Process sub/end blocks $action = $1, next if /Action = Find: (\w+)/; $text = $1, next if /Text = (.*)/; next if ! /^End/ or ! defined $text; # Here if we have an End and $text is defined $lookup{$action} = $text if defined $action; my $key = $main; $key = $lookup{$key} if $key =~ /^\w\w$/; push @{$lookup{$key}}, $text; $action = undef; $text = undef; } } Dump (\%lookup); #### __DATA__ Main Name = Countries End Sub Action = Find: NA Text = North America End Sub Action = Find: EU Text = Europe End --- Main Name = NA End Sub Action = Find: US Text = United States End Sub Action = Find: CA Text = Canada End Sub Action = Find: MX Text = Mexico End --- Main Name = US End Sub Action = Text = Boston End Sub Action = Text = Atlanta End --- Main Name = EU End Sub Action = Text = France End #### $HASH1 = { CA => 'Canada', Countries => [ 'North America', 'Europe' ], EU => 'Europe', Europe => [ 'France' ], MX => 'Mexico', NA => 'North America', "North America" => [ 'United States', 'Canada', 'Mexico' ], "United States" => [ 'Boston', 'Atlanta' ], US => 'United States' };