use strict; use warnings; use Data::Dump qw( pp ); my $ref = [ {} ]; my $prev_prefix = ''; while () { my ( $prefix, $text ) = split /> ?/; if ( $prefix gt $prev_prefix ) { $ref->[-1]{$prefix} = $text; } elsif ( $prefix eq $prev_prefix ) { $ref->[-1]{$prefix} .= $text; } else { push @$ref, { $prefix => $text }; } $prev_prefix = $prefix; } pp $ref; __DATA__ a> some random text b> b> a few random b> lines b> b> of more b> random b> b> text c> some more c> c> random c> text c> a> some random text b> b> a few random b> lines b> b> of more b> random b> b> text c> some more c> c> random c> text c>