非贪婪解析与pyparsing

Oli*_*Oli 5 python grammar parsing pyparsing

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

ids = 12 fields = name
Run Code Online (Sandbox Code Playgroud)

应该导致类似于: [('ids', '12'), ('fields', 'name')]

一个更复杂的例子:

ids = 12, 13, 14 fields = name, title
Run Code Online (Sandbox Code Playgroud)

应该导致类似于: [('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")
Run Code Online (Sandbox Code Playgroud)

有人能帮我吗 ?谢谢.

blu*_*ubb 7

第一个问题在于这一行:

val = ~key_equal + P.Word(P.alphanums+', ')
Run Code Online (Sandbox Code Playgroud)

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

你想要的是:

val = ~key_equal + P.delimitedList(P.Word(P.alphanums), ", ", combine=True)
Run Code Online (Sandbox Code Playgroud)

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

gr = P.Group(key_equal+val)
Run Code Online (Sandbox Code Playgroud)

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

gr = P.Group(P.OneOrMore(key_equal+val))
Run Code Online (Sandbox Code Playgroud)

所以正确的解决方案是:

>>> 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']]
Run Code Online (Sandbox Code Playgroud)