The problem you are trying to solve is generally not suitable for regular expressions, because arbitrarily nested content is not regular text. Instead, you may want to consider writing some sort of parser to find the nested terms. Here is one suggested script:
String input = "Hello (expr1(expr2)) Goodbye (Here is (another (deeply nested))) expression.";
int count = 0;
int start = 0;
int end;
for (int i=0; i < input.length(); ++i) {
if (input.charAt(i) == '(') {
++count;
if (count == 1) {
start = i;
}
}
if (input.charAt(i) == ')') {
--count;
if (count == 0) {
System.out.println(input.substring(start, i+1));
}
}
}
This works by keeping track of the number of opening and closing parentheses. When we see a (
and the count first goes from zero to one, we record the position in the string where that happened. At the other end, when we see a )
and the count returns to zero, we print the entire (possibly nested) term. In the more general case, you might use a stack data structure to handle the parsing, but a single integer count seems to work here.
The above script outputs the following:
(expr1(expr2))
(Here is (another (deeply nested)))