2011-08-12 42 views
5

Tôi đang cố gắng phân tích một dòng với pyparsing. Dòng này bao gồm một số (khóa, giá trị). Những gì tôi muốn nhận được là một danh sách (khóa, giá trị). Một ví dụ đơn giản:Phân tích cú pháp không tham lam với pyparsing

ids = 12 fields = name 

nên kết quả trong một cái gì đó như: [('ids', '12'), ('fields', 'name')]

Một ví dụ phức tạp hơn:

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

nên kết quả trong một cái gì đó như: [('ids', '12, 13, 14'), ('fields', 'name, title')]

PS: các tuple bên trong danh sách kết quả chỉ là một ví dụ. Nó có thể là một dict hoặc danh sách khác hoặc bất cứ điều gì, nó không phải là quan trọng.

Nhưng bất cứ điều gì tôi đã cố gắng cho đến nay tôi nhận được kết quả như sau: [('ids', '12 fields')]

Pyparsing được ăn quan trọng tiếp theo, coi đó cũng là một phần của giá trị.

Dưới đây là một số mẫu mã:

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

Ai đó có thể giúp tôi? Cảm ơn.

Trả lời

7

Vấn đề đầu tiên nằm trong dòng này:

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

Nó gợi ý rằng phần phù hợp với bất kỳ chuỗi chữ và số, tiếp theo là các literal ', ', nhưng thay vào đó nó phù hợp với bất kỳ chuỗi ký tự chữ và số, ','' '.

gì bạn muốn thay thế là:

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

Vấn đề thứ hai là bạn chỉ phân tích cặp một giá trị khóa:

gr = P.Group(key_equal+val) 

Thay vào đó, bạn nên phân tích càng nhiều càng tốt:

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

Vì vậy, các giải pháp đúng là:

0.123.
>>> 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: đã chỉnh sửa bài đăng của bạn một chút. Tôi nhận được kết quả tốt hơn với giải pháp của bạn. Vấn đề là tôi chỉ nhận được phần đầu tiên chứ không phải các phần sau. Tôi nhận được [('id', '12, 13,14 ')]. Tôi muốn nhận được [('id', '12, 13,14 '), (' trường ',' tên, tiêu đề ')] – Oli

+0

@Oli: Cảm ơn bạn đã nắm bắt. Tôi đã thêm giải pháp cho vấn đề thứ hai của bạn. – blubb

+0

Cảm ơn rất nhiều. Chính xác những gì tôi cần. – Oli

Các vấn đề liên quan