If you just gotta do this with a regex, try something like (needs Perl version 5.10+):
c:\@Work\Perl\monks>perl -wMstrict -le
"use 5.010;
;;
my $s =
'ab + (fun1( fun2( 3 +fun3 ( 4+(5+6) ))) ) + x + f ( 1 + 2 )'
+;
print qq{'$s'};
;;
$s =~ s{ ( \( (?: [^()]++ | (?1) )* \) ) }
{ (my $ns = $1) =~ tr/ \t\n\f//d; $ns; }xmsge;
print qq{'$s'};
"
'ab + (fun1( fun2( 3 +fun3 ( 4+(5+6) ))) ) + x + f ( 1 + 2 )'
'ab + (fun1(fun2(3+fun3(4+(5+6))))) + x + f (1+2)'
This uses Perl version 5.10 Extended Patterns (?1) (essential; see (?PARNO)) and the ++ "possessive quantifier" (inessential; could use a (?>pattern) "atomic" group). If you have Perl version 5.14+, the tr/// expression in the replacement block can simply be
{ $1 =~ tr/ \t\n\f//dr; }
(note the /r switch) with no need for substitute-on-copy.
I doubt this regex is the most optimal. I'd like to come up with a regex that just matches \s+ within a nested paren group and replaces with the empty string, but haven't figured this out yet.
Update: This is a little neater, more elegant, but still not quite what I was hoping for:
c:\@Work\Perl\monks\iaw4>perl -wMstrict -le
"use 5.010;
;;
my $s =
'ab + (fun1( fun2( 3 +fun3 ( 4+(5+6) ))) ) + x + f ( 1 + 2 )'
+;
print qq{'$s'};
;;
$s =~ s{ [(] (?: [^()]++ | (?0) )* [)] }
{ (my $ns = ${^MATCH}) =~ s/\s+//g; $ns; }xmsgpe;
print qq{'$s'};
"
'ab + (fun1( fun2( 3 +fun3 ( 4+(5+6) ))) ) + x + f ( 1 + 2 )'
'ab + (fun1(fun2(3+fun3(4+(5+6))))) + x + f (1+2)'
Note that the /p modifier is needed here because ${^MATCH} is used. And again, the replacement expression becomes a bit simpler with the use of the /r modifier of Perl 5.14+ on the s/// operation.
Give a man a fish: <%-{-{-{-<
|