Во-первых, вы хотите удалить скобки вместе с их содержанием? Хотя в заголовке вопроса указано «нет», я предполагаю, что вы тоже хотите убрать скобки.
Во-вторых, может ли содержимое между круглыми скобками содержать вложенные совпадающие скобки? Это решение предполагает да. Поскольку разновидность Java-регулярных выражений не поддерживает рекурсивные выражения, решение состоит в том, чтобы сначала создать регулярное выражение, которое соответствует «внутреннему» набору скобок, а затем применить это регулярное выражение итеративным образом, заменяя их изнутри. Вот протестированная Java-программа, которая корректно удаляет (возможно, вложенные) скобки и их содержимое:
import java.util.regex.*;
public class TEST {
public static void main(String[] args) {
String s = "stuff1 (foo1(bar1)foo2) stuff2 (bar2) stuff3";
String re = "\\([^()]*\\)";
Pattern p = Pattern.compile(re);
Matcher m = p.matcher(s);
while (m.find()) {
s = m.replaceAll("");
m = p.matcher(s);
}
System.out.println(s);
}
}
Тестовый ввод:
"stuff1 (foo1(bar1)foo2) stuff2 (bar2) stuff3"
Тестовый вывод:
"stuff1 stuff2 stuff3"
Обратите внимание, что решение lazy-dot-star никогда не будет работать, потому что оно не соответствует внутреннему набору скобок, когда они вложены. (т.е. он ошибочно совпадает: (foo1(bar1)
в приведенном выше примере.) И это очень часто совершаемая ошибка регулярного выражения: Никогда не используйте точку, когда есть более точное выражение! В в этом случае содержимое между «самым внутренним» набором совпадающих скобок состоит из любого символа, который не является открывающей или закрывающей скобкой , (т.е. используйте: [^()]*
вместо: .*?
).