非贪婪解析与pyparsing

时间:2011-08-12 08:27:15

标签: python parsing grammar pyparsing

我正在尝试用pyparsing解析一条线。该行由许多(键,值)组成。我想得到的是(键,值)列表。一个简单的例子:

ids = 12 fields = name

应该会产生类似:[('ids', '12'), ('fields', 'name')]

的内容

一个更复杂的例子:

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

应该会产生类似:[('ids', '12, 13, 14'), ('fields', 'name, title')]

的内容

PS:结果列表中的元组只是一个例子。它可能是一个字典或其他列表或其他什么,它并不重要。

但无论我到现在为止做了什么,我得到的结果如下: [('ids', '12 fields')]

Pyparsing正在吃下一把钥匙,因为它也是价值的一部分。

以下是示例代码:

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

有人能帮助我吗?感谢。

1 个答案:

答案 0 :(得分:7)

第一个问题在于这一行:

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

它表示该部分匹配任何字母数字序列,后跟文字', ',但它匹配任何字母数字字符序列,','' '

你想要的是:

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

第二个问题是你只解析一个键值对:

gr = P.Group(key_equal+val)

相反,您应该尽可能多地解析:

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

所以正确的解决方案是:

>>> 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']]