use strict; use warnings; while (defined (my $line = )) { next unless $line =~ /^(catch\s*)\[(.*)/s; my $prefix = $1; my ($body, $tail) = parse ($2); $line = "${prefix}{$body}$tail"; } continue { print $line; } sub parse { my ($tail) = @_; my $outStr = ''; while (defined $tail) { if ($tail =~ s/^([^[]*)\[(.*)//s) { my $prefix = $1; my $body; ($body, $tail) = parse ($2); $outStr .= "$prefix [$body]"; next if length $tail; } elsif ($tail =~ s/^([^\]]*)](.*)//s) { return "$outStr$1", $2; } $outStr .= $tail; $tail = ; } return $outStr, ''; } __DATA__ catch [ this; that; the; other; ] some random stuff that isn't a catch catch [ this[]; that + 1; the other; ] #### catch { this; that; the; other; } some random stuff that isn't a catch catch { this []; that + 1; the other; }