user1421716
user1421716

Reputation:

Regex to capture unpaired brackets or parentheses

As the title indicates, please, how do I capture unpaired brackets or parentheses with regex, precisely, in java, being new to java. For instance, supposing I have the string below;

Programming is productive, (achieving a lot, and getting good results), it is often 1) demanding and 2) costly.

How do I capture 1) and 2). I have tried:

([^\(\)][\)])

But, the result I am getting includes s) as below, instead of 1) and 2):

s), 1) and 2)

I have checked the link: Regular expression to match balanced parentheses, but, the question seem to be referring to recursive or nested structures, which is quite different from my situation. My situation is to match the right parenthesis or right bracket, along with any associated text that does not have an associated left parenthesis or bracket.

Upvotes: 1

Views: 1641

Answers (2)

WJS
WJS

Reputation: 40047

This is not a regex solution (obviously) but I can't think of a good way to do it. This simply uses a stack to keep track of parens.

For the input String "(*(**)**) first) second) (**) (*ksks*) third) ** fourth)( **)

It prints out

first)
second)
third)
fourth)

All other parentheses are ignored because they are matched.

      String s =
            "(*(**)**) first) second) (**) (*ksks*) third) ** fourth)( **)";
      Pattern p;
      List<String> found = new ArrayList<>();
      Stack<Character> tokens = new Stack<>();
      int pcount = 0;

      for (char c : s.toCharArray()) {
         switch (c) {
            case ' ':
               tokens.clear();
               break;
            case '(':
               pcount++;
               break;
            case ')':
               pcount--;
               if (pcount == -1) {
                  String v = ")";
                  while (!tokens.isEmpty()) {
                     v = tokens.pop() + v;
                  }
                  found.add(v);
                  pcount = 0;
               }
               break;
            default:
               tokens.push(c);
         }
      }
      found.forEach(System.out::println);

Note: Integrating brackets (]) into the above would be a challenge (though not impossible) because one would need to check constructs like ( [ ) ] where it is unclear how to interpret it. That's why when specifying requirements of this sort they need to be spelled out precisely.

Upvotes: 1

Emma
Emma

Reputation: 27743

Maybe,

\b\d+\)

might simply return the desired output, I guess.

Demo 1

Another way is to see what left boundary you might have, which in this case, I see digits, then what other chars we'd have prior to the closing curly bracket, and then we can design some other simple expression similar to:

\b\d[^)]*\) 

Demo 2

Test

import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class RegularExpression{

    public static void main(String[] args){

        final String regex = "\\b\\d[^)]*\\)";
        final String string = "Programming is productive, (achieving a lot, and getting good results), it is often 1) demanding and 2) costly.\n\n"
             + "Programming is productive, (achieving a lot, and getting good results), it is often 1a b) demanding and 2a a) costly.\n\n\n"
             + "Programming is productive, (achieving a lot, and getting good results), it is often 1b) demanding and 2b) costly.\n\n"
             + "It is not supposed to match ( s s 1) \n";

        final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
        final Matcher matcher = pattern.matcher(string);

        while (matcher.find()) {
            System.out.println("Full match: " + matcher.group(0));
            for (int i = 1; i <= matcher.groupCount(); i++) {
                System.out.println("Group " + i + ": " + matcher.group(i));
            }
        }


    }
}

Output

Full match: 1)
Full match: 2)
Full match: 1a b)
Full match: 2a a)
Full match: 1b)
Full match: 2b)
Full match: 1)

RegEx Circuit

jex.im visualizes regular expressions:

enter image description here

Upvotes: 2

Related Questions