pyparsing通过整数字节表示进行范围解析



我想知道pyparsing是否可以(以一种简单的方式(解析和检测几个字节上表示的一系列整数。这里有一段代码,我可以用来解析整数部分,然后对它做一些事情(只需打印后面的内容(:

from pyparsing import *
import struct
import re
min = 0x06A1D58C  # 111_269_260
max = 0x14B4CB1C  # 347_392_796
line_a = b'3Fx09x21xe4xc0KBHDVC'
ParserElement.setDefaultWhitespaceChars("")
expr = Suppress('3F') + Regex(re.compile(r'.{4}', re.DOTALL)).setResultsName('id') + Word(
srange('[A-Z]')).setResultsName('code')
expr.parseWithTabs()
try:
result = expr.parseString(line_a.decode('latin-1'), parseAll=False)
print(result.get('id').encode('latin-1'))
id= struct.unpack('!I', result.get('id').encode('latin-1'))[0]
code = result.get('code')
if min <= id <= max:
print(id, code)
except ParseException as e:
print(e.explain(e))

输出:

b't!xe4xc0'
153216192 KBHDVC

现在我想要的是能够有一个表达式,它将以整数形式指定范围以及后面的内容。通过这种方式,可以根据这个整数指定几种语法。

这可能吗?或者我必须把它放在解析之外作为后处理吗?

如果您希望将此转换和验证作为表达式定义的一部分,您可以添加解析时间回调,或解析操作:

binary_bytes = Regex(re.compile(r'.{4}', re.DOTALL))
def unpack(tokens):
return struct.unpack('!I', tokens[0].encode('latin-1'))[0]
binary_bytes.addParseAction(unpack)

解析操作可以获取解析后的令牌,并返回一个转换或增强的值。

您还可以使用如下解析操作来实现类似范围检查的过滤器:

def in_range(tokens):
if not (min <= tokens[0] <= max):
raise ParseException()

这种过滤器或验证器非常常见,您可以使用addCondition:来定义它

binary_bytes.addCondition(lambda tokens: min <= tokens[0] <= max)

我将您的示例重新格式化并重新打包如下:

def make_range_condition(minval, maxval):
in_range = lambda x, minval=minval, maxval=maxval: minval <= x <= maxval
return lambda t: in_range(t[0])
binary_bytes = Regex(re.compile(r'.{4}', re.DOTALL))
binary_bytes.addParseAction(lambda tokens: struct.unpack('!I', tokens[0].encode('latin-1'))[0])
binary_bytes.addCondition(make_range_condition(min, max))
ParserElement.setDefaultWhitespaceChars("")
expr = (Suppress('3F')
+ binary_bytes('id')
+ Word(srange('[A-Z]'))('code')
)
expr.parseWithTabs()
try:
result = expr.parseString(line_a.decode('latin-1'), parseAll=False)
print(result.dump())
except ParseException as e:
print(e.explain(e))

dump((提供以下输出:

[153216192, 'KBHDVC']
- code: 'KBHDVC'
- id: 153216192

最新更新