5

我最近开始使用 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']]]

希望这对将来有所帮助。

4

2 回答 2

2

我从更一般的意义上问了同样的问题,BNF 可以处理前向消费吗?. 这个问题的答案是否定的,因为上下文无关语法不知道会发生什么。值得庆幸的是,正如包的作者指出的那样,pyparsing 不仅仅是一种上下文无关的语法:

Pyparsing 包括countedArray完全按照您的要求执行的助手。它接受一个参数 expr,并将解析一个整数,后跟“n”个 expr 实例

他的回答中提供了一个更完整的解决方案和一个最小的工作示例。问题:PyParsing 前瞻和贪婪表达式也是您尝试做的一个很好的参考。

于 2012-06-20T04:37:56.080 回答
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
于 2012-06-19T16:11:01.333 回答