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

Есть ли одно регулярное выражение, которое может анализировать строку (в 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 для извлечения пути к файлу и сохраните его в python
  • Регулярное выражение: как совместить строку, содержащую «\ n» (новая строка)?
  • Захват названных групп в regex с re.findall
  • Могу ли я использовать именованные группы в регулярном выражении Perl для получения результатов в хеше?
  • среднее количество символов на слово в списке
  • Регулярное выражение Python для поиска содержимого ссылок разметки MediaWiki
  • Соответствие букв на любом языке
  • re.compile не соответствует моей строке
  •  
    Interesting Posts for Van-Lav

    сохранение изображений на питоне с очень высоким качеством

    настройка s3 для журналов в воздушном потоке

    Номер страницы python-docx

    Как комментировать счетчик с условием в наборе запросов Django

    Влияет ли резьба в GTK с Python в интроспекцию PyGObject?

    Как содержимое ответа «REST» «магически» преобразуется из «списка» в «строка»,

    Медленная производительность маркировки POS. Могу ли я сделать какое-то предварительное прогревание?

    Неправильно кэшированы ссылки Django-compressor / django-storageages; истекающий

    Почему Python не может увеличивать переменную в закрытии?

    matplotlib qt imshow animate

    Преобразование букв в нижний регистр

    Использование ключевого слова Python?

    Навигация вручную с помощью курсора через вложенные списки, только предоставляя «left ()» и «right ()» в качестве команд?

    Обратное определение декларативного класса SQLAlchemy из существующей базы данных MySQL?

    Python wmi c.Win32_PerfFormattedData_PerfOS_Processor win7 error

    Python - лучший язык программирования в мире.