2

I want to remove all the "unpartnered" or unpaired parenthesises from a string.

exampleStr = back-pay) zyzhk1219(17) zyzhk1329 zyzhk1595(15) zyzhk1988 zyzhk2004 zyzhk2131) jswioj((testsjkldf

The expected "parenthesis balanced" string should be

back-pay zyzhk1219(17) zyzhk1329 zyzhk1595(15) zyzhk1988 zyzhk2004 zyzhk2131 jswiojtestsjkldf

I saw some ruby based solution on stackoverflow. But, couldn't find one I can use in java.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Watt
  • 3,118
  • 14
  • 54
  • 85

2 Answers2

4

How it might be done in pseudo-code:

initialize parenLevel = 0
for each character in string
    if char is ( increment parenLevel
    if char is )
        if parenLevel = 0, remove bad paren
        else, decrement parenLevel
next

initialize parenLevel = 0
for each character in string in reverse
    if char is ) increment parenLevel
    if char is (
        if parenLevel = 0, remove bad paren
        else, decrement parenLevel
next

How it might be implemented in practice: http://ideone.com/K3s0X

Sample result:

back-pay zyzhk1219(17) zyzhk1329 zyzhk1595(15) zyzhk1988 zyzhk2004 zyzhk2131 jswiojtestsjkldf
mellamokb
  • 56,094
  • 12
  • 110
  • 136
  • 1
    Thanks a lot for the pseudo code and the java code. Before asking the question, I was trying something similar to your pseudo code, but, I kept running in infinite loop for some outlying conditions like multiple nested parenthesis. Your java code was super helpful in pointing my error. – Watt Mar 28 '12 at 05:20
  • Thought this might interest you http://stackoverflow.com/questions/9929168/how-to-remove-unbalanced-unpartnered-double-quotes-in-java – Watt Mar 29 '12 at 17:03
1

This works correctly on your example string:

s = s.replaceAll("([^()]*(?:\\([^()]*\\)[^()]*)*)[()]", "$1");

Or, in more readable form:

(
  [^()]*          # some non-parentheses
  (?:
    \([^()]*\)    # a matched pair of parens
    [^()]*        # some more non-parens
  )*
)
[()]              # one unpaired paren

I'm assuming you don't want to allow nested pairs of parentheses. For example, in this string:

"abc(def(ghi)jkl)mno"

...the first ( and the last ) should be removed, leaving this:

"abcdef(ghi)jklmno"

If you do want to allow nesting, there's no pure regex solution--at least, not in Java.

Alan Moore
  • 73,866
  • 12
  • 100
  • 156