2011-08-12 11 views
5

Próbuję parsować linię z pyparsingiem. Ta linia składa się z liczby (klucz, wartości). To, co chciałbym uzyskać, to lista (klucz, wartości). Prosty przykład:Non chciwy parsowanie z pyparsingiem

ids = 12 fields = name 

powinno spowodować coś takiego: [('ids', '12'), ('fields', 'name')]

bardziej złożony przykład:

ids = 12, 13, 14 fields = name, title 

powinno spowodować coś takiego: [('ids', '12, 13, 14'), ('fields', 'name, title')]

PS: krotki wewnątrz wynikowa lista jest tylko przykładem. Może to być dyktatura lub inna lista, nie jest to aż tak ważne.

Ale cokolwiek próbowałem do tej pory uzyskać wyniki takie jak: [('ids', '12 fields')]

Pyparsing je następnego klucza, biorąc pod uwagę to również część wartości.

Oto przykładowy kod:

import pyparsing as P 

key = P.oneOf("ids fields") 
equal = P.Literal('=') 
key_equal = key + equal 
val = ~key_equal + P.Word(P.alphanums+', ') 

gr = P.Group(key_equal+val) 
print gr.parseString("ids = 12 fields = name") 

Czy ktoś może mi pomóc? Dzięki.

Odpowiedz

7

Pierwszy problem polega na tym wierszu:

val = ~key_equal + P.Word(P.alphanums+', ') 

To sugeruje, że część pasuje dowolny ciąg alfanumeryczny, następnie dosłownym ', ', ale zamiast tego pasuje dowolny ciąg znaków alfanumerycznych, ',' i ' '.

Co tylko chcesz, a nie to:

val = ~key_equal + P.delimitedList(P.Word(P.alphanums), ", ", combine=True) 

Drugim problemem jest to, że tylko jeden przeanalizować parę klucz-wartość:

gr = P.Group(key_equal+val) 

Zamiast tego, należy przeanalizować jak najwięcej:

gr = P.Group(P.OneOrMore(key_equal+val)) 

Więc poprawnym rozwiązaniem jest:

>>> import pyparsing as P 
>>> key = P.oneOf("ids fields") 
>>> equal = P.Literal('=') 
>>> key_equal = key + equal 
>>> val = ~key_equal + P.delimitedList(P.Word(P.alphanums), ", ", combine=True) 
>>> gr = P.OneOrMore(P.Group(key_equal+val)) 
>>> print gr.parseString("ids = 12, 13, 14 fields = name, title") 
[['ids', '=', '12, 13, 14'], ['fields', '=', 'name, title']] 
+0

PS: nieznacznie edytowałem twój post. Dostaję lepszy wynik z twoim rozwiązaniem. Problem polega na tym, że dostaję tylko pierwszą część, a nie następujące części. Otrzymuję [('ids', '12, 13,14 ')]. Chciałbym otrzymać [("ids", "12, 13,14"), ("pola", "imię, tytuł")] – Oli

+0

@Oli: Dzięki za połów. Dodałem rozwiązanie do twojego drugiego problemu. – blubb

+0

Dziękuję bardzo. Dokładnie to, czego potrzebuję. – Oli