Deep parenthesis matching is not doable with regular expressions.
You could do it if you had a fixed pattern - like three parenthesis deep, and a second set of sibling at the top level parenthesis, and so on. But matching arbitrary closing parenthesis with the opening ones is not easily feasible with regexes only (if there is a practical way of doing it with regexes at all).
It is much easier to write a couple lines of Python code and use Python itself to match the outer parentheses groups - as you can just count the number of open parentheses in a stream. So, soemthing along this - (it can be made in less lines):
def extract_parentheses_groups(text):
count = 0
groups = []
buffer = ""
for char in text:
if char == "(":
if count == 0 and buffer.strip():
groups.append(buffer.strip())
buffer = ""
count += 1
buffer += char
if char == ")":
count -= 1
if count == 0:
groups.append(buffer.strip())
buffer = ""
if buffer.strip():
groups.append(buffer.strip())
return groups
Running your example input through this I get:
In [17]: a = """if ((a and b) or (a and)) or (c and d) or (e and f)"""
In [18]: extract_parentheses_groups(a)
Out[18]: ['if', '((a and b) or (a and))', 'or', '(c and d)', 'or', '(e and f)']