前言

  • 技术栈
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"
    }
  }
}

相关资料

文章

本文出自 qbit snap

qbit
268 声望279 粉丝