sub blah { return '}'; } #### extract_bracketed($code, '{}') to handle this, but even that will still bomb on curlies in comments:

sub blah { # } is such a neat character return '}'; } #### $code = blockize($code); sub blockize { my ($code) = @_; # describe a block: use re 'eval'; my $comment = qr/#[^\n]*/; my $single_quoted = qr/' [^\\']+ (?: \\. [^\\']+ )* '/; my $double_quoted = qr/" [^\\"]+ (?: \\. [^\\"]+ )* "/; my $block; $block = qr/ { (?: (?> [^#'"{}]+ ) | $comment | $single_quoted | $double_quoted | (??{$block}) )* } /x; # now that we have a block definition set up, its just a simple substitution $code =~ s/sub \s+ (\w+) \s+ ($block)/ format_code("$1", "$2") /gex; return $code; sub format_code { my ($name, $block) = @_; $block =~ s/\n/\n /g; return "{\n sub $name $block\n}"; } } #### sub blockize { my ($code) = @_; # describe a block: use re 'eval'; use Regex::Common qw(delimited comment); my $block; $block = qr/ { (?: (?> [^#'"{}]+ ) | $RE{comment}{Perl} | $RE{delimited}{-delim=>"'"} | $RE{delimited}{-delim=>'"'} | (??{$block}) )* } /x; # now that we have a block definition set up, its just a simple substitution $code =~ s/sub \s+ (\w+) \s+ ($block)/ format_code("$1", "$2") /gex; return $code; sub format_code { my ($name, $block) = @_; $block =~ s/\n/\n /g; return "{\n sub $name $block\n}"; } }