2012-06-19 7 views
5

Recentemente ho iniziato ad usare python/pyparsing per elaborare una serie di valori esadecimali e sto avendo problemi con questo: Considerate questa stringa:Usa token come variabile nel pyparsing

string = "10020304059917368584304025326" 

voglio la fine risultano essere questo:

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

si supponga che 04 è un tag, che significa che i dati (stesso concetto in ASN.1), e 05 è la dimensione di tali dati. Non vedo come utilizzare la variabile dimensione sul codice di pyparsing. Il meglio che posso fare è:

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

Qualsiasi aiuto sarebbe molto apprezzato.


PS: Dopo l'aiuto di Hooked, il mio codice finale è:

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()) 

che stampa:

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

Spero che questo aiuti in futuro.

risposta

2

ho chiesto la stessa domanda in un senso più generale, Can a BNF handle forward consumption?. La risposta a questa domanda era no, in quanto una grammatica libera dal contesto non può sapere cosa sta succedendo. Per fortuna, pyparsing è più di una grammatica context-free come l'autore del pacchetto points out:

Pyparsing include l'assistente countedArray che fa esattamente quello che chiedi. Prende un singolo argomento expr e analizza un numero intero seguito da istanze 'n' di expr

Nella sua risposta viene fornita una soluzione molto più completa con un esempio di lavoro minimo. La domanda: PyParsing lookaheads and greedy expressions è anche un buon riferimento per ciò che stai cercando di fare.

+0

Grazie, questo è esattamente ciò di cui avevo bisogno. – Kiji

0

Questo lavoro dovrebbe funzionare? Non usa il pyparsing, ma registra sottoliste di lunghezza variabile quando vede '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 
+0

Sfortunatamente non per me. L'esempio che ho dato è solo una parte di ciò che ho intenzione di fare, quindi è fondamentale usare il pyparsing (ho una grande quantità di tag, che rappresentano varie dimensioni). Grazie per l'aiuto! – Kiji

+0

Whammy. In bocca al lupo! – cjohnson318