use strict; my @array = qw/ ***1*** first second ***end1*** ***2*** third fourth ***end2*** /; my @new_array; foreach my $element ( @array ) { my $mark = quotemeta "***"; my $where = ( $element =~ /$mark(\d+)$mark/ .. $element =~ /${mark}end$1+$mark/ ); push @{$new_array[ $1 - 1 ]}, $element if $where != 1 and $where !~ /E/ ; } use Data::Dumper; print Dumper \@new_array;