use Data::Dumper; use strict; use warnings; my %parse_tree; my $category; while (my $line = ) { if ($line =~ /^(\w+:)$/) { $category = $1; $parse_tree{ $category} = []; } else { push @{$parse_tree{ $category}}, $line; } } print Dumper( \%parse_tree); __DATA__ heading1: text1 text2 text3 heading2: text4 text5 text6 #### $VAR1 = { 'heading1' => [ 'text1 ', 'text2 ', 'text3 ' ], 'heading2' => [ 'text4 ', 'text5 ', 'text6 ' ] };