在pyparsing中使用token作为变量

时间:2012-06-19 14:05:59

标签: python-3.x pyparsing

我最近开始使用python / pyparsing处理一串十六进制值,我遇到了这个问题: 考虑一下这个字符串:

string = "10020304059917368584304025326"

我希望最终结果如下:

['10', '02', '03', ['04', '05', '9917365843'], ['04', '02', '5326']]

假设04是表示数据的标签(与ASN.1中的概念相同),05是该数据的大小。我没有看到如何在pyparsing代码上使用size变量。我能做的最好的事情是:

byte = Word(hexnums, exact=2)
process = byte + byte + byte + Word(hexnums)
newstring = process.parseString(string)
print (newstring.dump())

非常感谢任何帮助。


PS :在Hooked的帮助下,我的最终代码为:

from pyparsing import *

string = "10 02 03 04 05 99 17 36 58 43 04 02 53 26"

tag = Word(hexnums, exact=2)
size =  Word(hexnums)
array = Group(tag + countedArray(size))

process = tag + tag + tag + ZeroOrMore(array)

newstring = process.parseString(string)
print (newstring.dump())

打印哪些:

['10', '02', '03', ['04', ['99', '17', '36', '58', '43']], ['04', ['53', '26']]]

希望这有助于将来。

2 个答案:

答案 0 :(得分:2)

我在更广泛的意义上问了同样的问题Can a BNF handle forward consumption?。这个问题的答案是否定的,因为无上下文语法无法知道将要发生什么。值得庆幸的是,pyparsing不仅仅是一个无上下文的语法,而是作为包points out的作者:

  

Pyparsing包含帮助器countedArray,它完全符合您的要求。它需要一个参数expr,并将解析一个整数,后跟'n'个expr实例

在他的回答中提供了一个更完整的解决方案,其中包含一个最小的工作示例。问题:PyParsing lookaheads and greedy expressions也是您尝试做的很好的参考。

答案 1 :(得分:0)

这会有用吗?它不使用pyparsing,但它会在看到'04'时记录可变长度的子列表。

def func( s ):
    d = []
    # while s isn't empty
    while len(s) != 0:
        b = s[0:2]
        if b != '04':
            # if b isn't '04' append it to d
            d.append( b )   
            # shorten s
            s = s[2:]
        else:
            # take the length, as a string
            l = s[2:4]
            # take the length, as an integer
            n = int(s[2:4])
            # record b='04', the length, and then the next values
            d.append( [ b, l, s[4:4+n*2] ] )
            # shorten s
            s = s[4+n*2:]
    return d