前言
Python 3.11
pyparsing 2.4.7
loguru 0.7.2
xmltodict 0.13.0
案例
測試解析 與 或
# encoding: utf-8
# author: qbit
# date: 2023-12-14
# summary: pyparsing 2.x 解析測試,測試 AND OR
import json
import xmltodict
import pyparsing as pp
from loguru import logger
line = 'Apple gt 6 AND (Plum eq 7 OR Pear lt 8)'
operator = pp.Word('gt') | pp.Word('eq') | pp.Word('lt')
field = pp.Word(pp.alphas)
value = pp.Word(pp.nums)
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 = exprForward.parseString(line, parseAll=True)
dic = xmltodict.parse(result.asXML())
logger.debug(f"result json: \n{json.dumps(dic, indent=2)}")
{
"Result": {
"Result": {
"Expr": [
{
"field": "Apple",
"operator": "gt",
"value": "6"
},
{
"Expr": [
{
"field": "Plum",
"operator": "eq",
"value": "7"
},
{
"field": "Pear",
"operator": "lt",
"value": "8"
}
],
"logic": "OR"
}
],
"logic": "AND"
}
}
}
setParseAction 函數測試
# encoding: utf-8
# author: qbit
# date: 2023-12-15
# summary: pyparsing 2.x 解析測試,用 setParseAction 轉大寫化
import json
import xmltodict
import pyparsing as pp
from loguru import logger
line = 'aa AND bb OR cc'
def action(token: pp.ParseResults):
r""" token 是列表形式 ['aaa'] """
return token[0].upper()
atom: pp.Word = pp.Word(pp.alphas).setParseAction(action)
logicAND = pp.Word('AND')('logic')
logicOR = pp.Word('OR')('logic')
logicNOT = pp.Word('NOT')('logic')
exprForward: pp.Forward = pp.infixNotation(atom('atom'), [
(logicAND, 2, pp.opAssoc.LEFT, ),
(logicOR, 2, pp.opAssoc.LEFT, ),
(logicNOT, 1, pp.opAssoc.RIGHT, ),
]).setResultsName('result', True)
result: pp.ParseResults = exprForward.parseString(line, parseAll=True)
logger.debug(f"result: \n{result}")
dic = xmltodict.parse(result.asXML())
logger.debug(f"result json: \n{json.dumps(dic, indent=2)}")
result:
[[['AA', 'AND', 'BB'], 'OR', 'CC']]
result json:
{
"result": {
"result": {
"atom": [
{
"atom": [
"AA",
"BB"
],
"logic": "AND"
},
"CC"
],
"logic": "OR"
}
}
}
相關資料
庫
- https://pypi.org/project/pyparsing/
- https://pypi.org/project/boolean-parser
- https://pypi.org/project/parsimonious/
- https://pypi.org/project/sympy/
文章
- pyparsing 學習(博客園)
- 取代正則-使用pyparsing來定製自己的解析器(知乎)
- Pyparsing快速構建解釋器 | 實戰搜索查詢語法(知乎)
- parsing logical expression with pyparsing
- Pyparsing實戰(知乎)
本文出自 qbit snap