2

I want to split string according to delimiter but only outside parenthesis. Is there any library (built-in or not) that does so? Example: If delimiter is ":" then: string "a:b:c" should be split to "a","b","c" string "a(b:c):d" should be split to "a(b:c)","d"

Thanks

duduamar
  • 3,628
  • 6
  • 32
  • 50
  • 3
    I've answered a similar question over here: - http://stackoverflow.com/questions/7804335/split-string-on-spaces-except-if-between-quotes-i-e-treat-hello-world-as – aioobe Jul 22 '12 at 07:42
  • 1
    ...and here: http://stackoverflow.com/questions/9656212/java-splitting-a-string-while-ignoring-any-delimiters-between-brackets – aioobe Jul 22 '12 at 07:49
  • so your answer is that it can't be done using regular expressions? Then how can it be done? I can parse it manually but prefer something that is ready and tested :) – duduamar Jul 22 '12 at 07:53
  • I'm saying it depends on how you want to for instance treat `"a(b:(c:d)):e"`. In general, I would strongly advice you to use a parser generator. – aioobe Jul 22 '12 at 07:58
  • a nice spitter is that one provided by google guava libraries, you can check it out here: http://code.google.com/p/guava-libraries/wiki/StringsExplained#Splitter – JayZee Jul 22 '12 at 07:59

1 Answers1

0

The other commenters are right that you are probably best off using a grammar library. If, however, this is a one off thing and you'd rather just deal with it quickly, this algorithm should handle it in a clear fashion, and will deal with nested parentheses. Note: I'm assuming your parentheses are well balanced, i.e., no right parentheses that don't have an opening left paren before them.

int parenDepth = 0;
int start = 0;
List<String> splits = new ArrayList<String>();

for(int i = 0; i < str.length(); i++)
{
    char ch = str.get(i);
    if(ch == '(')
         parenDepth++;
    else if(ch == ')')
         parenDepth--;
    else if(parenDepth == 0 && ch ==',')
    {
         if(start != i) // comment out this if if you want to allow empty strings in 
                        // the splits
             splits.add(str.substring(start, i));
         start = i+1;
    }
}

splits.add(str.substring(start));
rmehlinger
  • 942
  • 1
  • 7
  • 22