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)
Вопрос:
Каков наилучший способ выделения булевой строки выражения?
- Как определить, является ли ввод пользователем допустимым шестнадцатеричным числом?
- Модуль google_auth_httplib2 не найден после того, как pip установил google-cloud. Как я могу его исправить?
- Преимущества os.path.splitext над регулярным .split?
- Элегантный способ распаковать ограниченные значения dict в локальные переменные в Python
- Пакет номеров Python?
Построить парсер:
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))
- Используйте Python os.walk для определения списка файлов
- Как сконденсировать эту функцию?
- Как назначить функции в словаре?
- Добавить предыдущий элемент в текущий список, затем назначить переменной – Python 3.5.2
- Почему заказанный выбор в pyparsing не подходит для моего варианта использования?
- Python и инициализация переменных класса – как использовать метод класса для инициализации членов?
- Добавить пространство имен к объекту безопасности WSSE по умолчанию в Suds
- urllib3 на python 2.7 Ошибка SNI в Google App Engine
- AttributeError при перечислении всех объектов из хранилища данных Google App Engine