前言
Python 3.11 pyparsing 3.1.2
案例
# encoding: utf-8 # author: qbit # date: 2024-04-23 # summary: 化简括号冗余的与或非逻辑表达式 import pyparsing as pp line = '(((owner=111 AND doc_type=222))) OR author=333 OR organ=444 AND ((NOT pub_year>555))' operator = ( pp.Literal(r'=') | pp.Literal(r'>') ) field = pp.Word(pp.alphanums + '_') value = pp.Word(pp.alphanums) exprGroup: pp.Group = pp.Group(field("field") + operator("operator") + value("value")) logicAND = pp.Word('AND')('logic') logicOR = pp.Word('OR')('logic') logicNOT = pp.Word('NOT')('logic') exprForward = pp.infixNotation( exprGroup("Expr"), [ (logicAND, 2, pp.opAssoc.LEFT, ), # 第二个参数为操作数的个数,并不是结合优先级 (logicOR, 2, pp.opAssoc.LEFT, ), (logicNOT, 1, pp.opAssoc.RIGHT, ), ] ).setResultsName("Result", True) result: pp.results.ParseResults = exprForward.parseString(line, parseAll=True) def list2qs(lst): if (len(lst) == 1) and isinstance(lst[0], list): # 列表中只有一个列表元素 return list2qs(lst[0]) if lst[0] == 'NOT': return f"(NOT {list2qs(lst[1])})" if lst[1] == 'AND': return ' AND '.join( [list2qs(x) for x in lst[0::2]]) # 步长为2取数据 if lst[1] == 'OR': return ' OR '.join( [list2qs(x) for x in lst[0::2]]) # 步长为2取数据 match lst[1]: case r'=': return f"{lst[0]}={lst[2]}" case r'>': return f"{lst[0]}>{lst[2]}" case _: pass qs = list2qs(result.as_list()) print(f"冗余表达式: {line}") print(f"简化表达式: {qs}")
冗余表达式: (((owner=111 AND doc_type=222))) OR author=333 OR organ=444 AND ((NOT pub_year>555)) 简化表达式: owner=111 AND doc_type=222 OR author=333 OR organ=444 AND (NOT pub_year>555)
相关资料
库
文章
本文出自 qbit snap
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。