norkakn has asked for the wisdom of the Perl Monks concerning the following question:

I searched CPAN and couldn't find anything helpful (or at least that I could tell was helpful), so here goes:

I need to split a string based on commas, except if the comma is inside a parenthesis.

"a,b,c" => ("a","b","c")
"a,(b,c)" => ("a","(b,c)"
"a,A(b,(c,d))" => ("a","A(b,(d,c))"


Thanks!
  • Comment on Splitting a string while respecting parentheses

Replies are listed 'Best First'.
Re: Splitting a string while respecting parentheses
by ccn (Vicar) on Dec 05, 2008 at 23:28 UTC
Re: Splitting a string while respecting parentheses
by graff (Chancellor) on Dec 06, 2008 at 03:09 UTC
    Doing a proper job of rolling your own calls for character-by-character parsing. Parse::RecDescent is a worthwhile tool to learn, but if you'll never get more complicated than the OP task, this would probably suffice:
    use strict; while (<DATA>) { chomp; my $nested = 0; my @out = (); my $tkn = ''; for my $c ( split // ) { if ( $c eq '(' ) { $nested++; $tkn .= $c; } elsif ( $c eq ')' ) { if ( $nested ) { $nested--; } else { warn "unmatched ')' in $_\n"; } $tkn .= $c; } elsif ( $nested or $c ne ',' ) { $tkn .= $c; } elsif ( $tkn ) { push @out, $tkn; $tkn = ''; } } if ( $nested ) { warn "$nested unmatched '(' in $_\n"; } else { push @out, $tkn if ( $tkn ); } print join( " ;; ", @out ), "\n" if ( @out ); } __DATA__ a,b,c,d x,z, a,(b,c(d,e)f)),h (1,2)(345) ,(6,7),(789) ((345,6),567 ,,m,,n,,(o,,p),,q,,
      Thanks, this is the road I'll go down.