my $result=""; my $re = qr/ (.*?) # Everything before the first tag $this->{mask_start} \Q$key\E(.*?) $this->{mask_end} (.*?) $this->{mask_start_close} (?=(.*)) # capture the rest, to get end of template /x; my $trailingText; while($this->{template} =~ /$re/g) { $result.=$1; # add the stuff between tags to results my $params = $this->mask_block_params($2, $3); my $html = &$callback($key, $params); $result.=$html; $trailingText=$4; } $result.=$trailingText; # $result should be what you're looking for. I think :)