#!/usr/bin/perl -w # # goss2 # # "escape" every comma within nested non-escaped brackets by # preceeding it with a backslash. # # created 1997-12-28 # modified 1999-05-28 use strict; sub escape_commas { my $in = shift; # split $in on escaped brackets my @esc = split /(\\[][])/, $in, -1; # is the first element an escaping bracket? my $do_this_esc = ($esc[0] =~ /\\[][]/) ? 0 : 1; # keep track of how deeply the "real" brackets are nested. my $nesting = 0; foreach my $esc (@esc) { # we only want to do every other one. unless ($do_this_esc) { $do_this_esc = 1; next; } $do_this_esc = 0; # split into bracketed and non-bracketed text. my @brack = split /([][])/, $esc; foreach (@brack) { # if it's a bracket, do do some accounting $_ eq '[' && do { ++$nesting; next; }; $_ eq ']' && do { --$nesting; next; }; # otherwise, if we're at the base level, replace all commas with # backslash+comma. note that this currently does not allow for # escaped commas. # $nesting > 0 && do { s/,/\\,/g; }; # attempt to handle escaped commas $nesting > 0 && do { s/((\\\\)|(\\,)|(,))/defined $4 ? '\\,' : $1/ge; }; } # fix anything we munged $esc = join "", @brack; } # then splat it all together. return join "", @esc; } my @in = ('[here, and here,,,] but not here,', '[but what about here\\, ?]nor \\[here,\\]'); my @out = ('[here\, and here\,\,\,] but not here,', '[but what about here\\, ?]nor \\[here,\\]'); foreach (@in) { my $out = escape_commas($_); print qq[in: "$_"\nout: "$out"\n]; } exit 0;