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