use strict; use warnings; use Text::Balanced qw(extract_bracketed); my $code = "sub blah {\n {}\n {}\n {}\n {}\n} and some other stuff sub another {\n}"; for my $end (find_ends($code)) { $code = substr($code, 0, $end) . "}" . substr($code, $end); } $code =~ s/sub/{sub/g; print "$code\n"; sub find_ends { local $_ = $_[0]; my @ends; while (/(sub\s+\S+\s*)(?={)/g) { () = extract_bracketed($_, '{}'); push @ends, pos; } return @ends; }