Выполнить булевскую арифметику, включая круглые скобки с регулярным выражением?

Есть ли одно регулярное выражение, которое может анализировать строку (в Python и / или Javascript, не обязательно должно быть одним и тем же выражением), которое представляет собой простую логическую арифметику? Например, я хочу проанализировать эту строку:

a and (b and c) and d or e and (f or g) 

При условии, что:
* круглые скобки не гнездятся
* члены a, b, …, z не являются подвыражениями

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

Я успел написать наивное регулярное выражение для разбора логической арифметики без круглых скобок.

Есть идеи?

3 Solutions collect form web for “Выполнить булевскую арифметику, включая круглые скобки с регулярным выражением?”

Обычно вы должны использовать, например, рекурсивный парсер спуска для этой задачи, но вы можете захватить все части (токены) с помощью регулярного выражения:

 x = 'a and (b and c) and d or e and (f or g)' import re matches = re.findall(r'\(.*?\)|\w+', x) print ','.join(matches) 

Операторы обычно имеют разный приоритет . Сначала будут оцениваться скобки, затем выражения и, наконец, выражения or с порядком слева направо в случае равного приоритета. Вы говорите, что хотите сначала вернуть скобки, но на самом деле то, что вы обычно делаете, – это использование частей, создающих дерево выражений, и их рекурсивное вычисление.

Предполагая, что никакая вложенность не упрощает его до уровня, где может использоваться регулярное выражение. Регулярное регулярное выражение, которое должно быть (предполагается и / или только, может быть легко расширено):

 >>> expr = 'a and (b and c) and d or e and (f or g)' >>> regex = re.compile('\((\w+)\s+(and|or)\s+(\w)\)|(\w+)') >>> results = regex.findall(expr) >>> results = [i[:3] if i[0] else i[3] for i in results] >>> results ['a', 'and', ('b', 'and', 'c'), 'and', 'd', 'or', 'e', 'and', ('f', 'or', 'g')] 

Теперь у вас есть скобки в виде кортежей из 3 строк (операнд-оператор-операнд), а остальная часть строки – как строки для каждого токена (оператор или операнд).

Вы можете пройти через список, оценить каждое выражение в скобках и заменить его результатом. Как только это будет сделано, вы сможете пройти через него снова и оценить либо слева направо, либо в соответствии с некоторыми правилами приоритета, которые вы задали (например, продолжайте оценивать AND только до тех пор, пока не закончите AND, а затем начните оценивать ORs).

Страница « Примеры» на вики- странице pyparsing включает образец SimpleBool.py, который будет анализировать и оценивать выражения, такие как:

 test = ["p and not q", "not not p", "not(p and q)", "q or not p and r", "q or not (p and r)", "p or q or r", "p or q or r and False", ] 

(Хм, нет примеров с вложенными парсерами, но они тоже поддерживаются).

Фактический синтаксический анализатор полностью определяется с помощью этого кода:

 boolOperand = Word(alphas,max=1) | oneOf("True False") boolExpr = operatorPrecedence( boolOperand, [ ("not", 1, opAssoc.RIGHT, BoolNot), ("and", 2, opAssoc.LEFT, BoolAnd), ("or", 2, opAssoc.LEFT, BoolOr), ]) 

В оставшейся части примера приведены реализации BoolNot, BoolOr и BoolAnd. Конструкция operatorPrecedence определяет последовательность операций, их арность и ассоциативность и, необязательно, класс, который должен быть сконструирован с анализируемыми элементами. operatorPrecedence затем заботится об определении грамматики, включая рекурсивное определение boolExpr в вложенных круглых скобках. Полученная структура похожа на вложенный АСТ с использованием заданных классов BoolXxx. Эти классы, в свою очередь, определяют методы eval так что выражения могут анализироваться и оцениваться с использованием этого кода:

 p = True q = False r = True for t in test: res = boolExpr.parseString(t)[0] print t,'\n', res, '=', bool(res),'\n' 

pyparsing сам по себе является несколько длинным модулем, но он является единственным исходным файлом, поэтому его размер установки довольно мал. Лицензия MIT разрешает как некоммерческое, так и коммерческое использование.

  • RegEx Tokenizer: разделить текст на слова, цифры, знаки препинания и интервалы (ничего не удалять)
  • разбор недопустимого тега привязки с помощью BeautifulSoup или Regex
  • Список всех шаблонов, которые соответствует регулярному выражению
  • Режимы Python поддерживают что-то вроде Perl \ G?
  • Замена HTML-тегов с использованием регулярных выражений и python
  • Как заменить N-й вид иглы в стоге сена? (Python)
  • Чтение Python Regex в комментариях стиля c
  • соответствие регулярному выражению с дополнительным lookahead
  • Python - лучший язык программирования в мире.