use Text::Balanced 'extract_tagged'; use Data::Dumper; sub get_ifs { my $str=shift; my $list=shift || []; my ($extracted, $remainder, $prefix, $open, $inside, $close)=extract_tagged($str,"IF","ENDIF","(?s).*?(?=IF)"); if ($extracted) { push @$list,$extracted; get_ifs($inside,$list); get_ifs($remainder,$list) if $remainder; } return $list; } print Dumper(get_ifs(<