Python – лучший способ выделить строку с булевым выражением

У меня есть логическая строка выражения, которую я хотел бы разделить:

condition = "a and (b or (c and d))" 

Или скажем:
Я хочу иметь доступ к содержимому строки между двумя скобками.
Я хочу получить следующий результат:

 "(b or (c and d))" "(c and d)" 

Я пробовал следующее с регулярными выражениями (не работает)

 x = re.match(".*(\(.*\))", condition) print x.group(1) 

Вопрос:
Каков наилучший способ выделения булевой строки выражения?

Построить парсер:

  Condition ::= Term Condition' Condition' ::= epsilon | OR Term Condition' Term ::= Factor Term' Term' ::= epsilon | AND Factor Term' Factor ::= [ NOT ] Primary Primary ::= Literal | '(' Condition ')' Literal ::= Id 

Это то, что вы не можете сделать с простым регулярным выражением. Вам необходимо проанализировать текст. Очевидно, что пираринг отлично подходит для этого.

Как все сказали, вам нужен парсер.

Если вы не хотите его устанавливать, вы можете начать с этого простого синтаксического анализатора сверху вниз (возьмите здесь последний пример кода)

Удалите все, что не связано с вашими потребностями (+, -, *, /, is, lambda, if, else, …). Просто скопируйте скобки and or . Вы получите двоичную древовидную структуру, созданную из вашего выражения. В токенизаторе используется встроенный tokenize ( import tokenize ), который является лексическим сканером для исходного кода Python, но отлично import tokenize для простых случаев, подобных вашим.

Если ваши требования достаточно просты, вам не нужен синтаксический анализатор. Соответствующие круглые скобки могут быть легко достигнуты с использованием стека.

Вы можете сделать что-то вроде следующего:

 condition = "a and (b or (c and d))" stack = [] for c in condition: if c != ')': stack.append(c) else: d = c contents = [] while d != '(': contents.insert(0, d) d = stack.pop() contents.insert(0, d) s = ''.join(contents) print(s) stack.append(s) 

производит:

 (c and d) (b or (c and d))