use 5.010; use strict; use warnings; my %h; my @depth; while (){ chomp; /^(\s*)/; # 'cause it's 4 spaces here, not tabs my $level = length($1) / 4; s/^\s+//; my ($key, $val) = split /\s{2,}/, $_, 2; my $h = $level == 0 ? \%h : $depth[$level - 1]; $h->{$key}{DESCRIPTION} = $val; $depth[$level] = $h->{$key}; } use Data::Dumper; print Dumper \%h; __DATA__ Assault Assault Battery Assault and Battery Sexual Sexual Assault Deadly Assault with a deadly weapon with Assault with a deadly weapon without Assault without a deadly weapon Aggravated Aggravated Assault #### VAR1 = { 'Assault' => { 'Sexual' => { 'DESCRIPTION' => 'Sexual Assault' }, 'Battery' => { 'DESCRIPTION' => 'Assault and Battery' }, 'DESCRIPTION' => 'Assault', 'Aggravated' => { 'DESCRIPTION' => 'Aggravated Assault' }, 'Deadly' => { 'DESCRIPTION' => 'Assault with a deadly weapon', 'without' => { 'DESCRIPTION' => 'Assault without a deadly weapon' }, 'with' => { 'DESCRIPTION' => 'Assault with a deadly weapon' } } } }; #### sub lookup { my $h = \%h; $h = $h->{$_} for @_; return $h->{DESCRIPTION}; } say lookup 'Assault'; say lookup qw/Assault Deadly with/;