You can use the following regex to use in split:
\([^()]*\)(*SKIP)(*F)|\s*,\s*
With \([^()]*\)
, we match a (
followed with 0 or more characters other than (
or )
and then followed with )
. We fail the match with (*SKIP)(*F)
if that parenthetical construction is found, and then we only match the comma surrounded with optional whitespaces.
See demo
#!/usr/bin/perl
my $string= "blah, foo(a,b), bar(c,d), yo";
my @string = split /\([^()]*\)(*SKIP)(*F)|\s*,\s*/, $string;
foreach(@string) {
print "$_\n";
}
To account for commas inside nested balanced parentheses, you can use
my @string = split /\((?>[^()]|(?R))*\)(*SKIP)(*F)|\s*,\s*/, $string;
Here is an IDEONE demo
With \((?>[^()]|(?R))*\)
we match all balanced ()
s and fail the match if found with the verbs (*SKIP)(*F)
, and then we match a comma with optional whitespace around (so as not to manually trim the strings later).
For a blah, foo(b, (a,b)), bar(c,d), yo
string, the result is:
blah
foo(b, (a,b))
bar(c,d)
yo