動態

詳情 返回 返回

pyparsing 2.x 案例(qbit) - 動態 詳情

前言

  • 技術棧
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
user avatar labilezhu 頭像 myskies 頭像 chiqingdezhentou 頭像 yixiyidong 頭像
點贊 4 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.