Python pyparsing检索动态长度字符串的结果键

Python pyparsing检索动态长度字符串的结果键,python,iterator,pyparsing,Python,Iterator,Pyparsing,我尝试在pyparsing中解析组列表。这些组可能属于不同的类型,我希望在结果中检索该类型。因为同一类型可能有多个组,所以字典没有帮助。 为了说明我的问题,我举了一个简单的例子: import pyparsing as pars dot = pars.Literal(".") question = pars.Literal("?") comma = pars.Literal(",") total = pars.OneOrMore( pars.Group( pars.O

我尝试在
pyparsing
中解析组列表。这些组可能属于不同的类型,我希望在结果中检索该类型。因为同一类型可能有多个组,所以字典没有帮助。 为了说明我的问题,我举了一个简单的例子:

import pyparsing as pars

dot = pars.Literal(".")
question = pars.Literal("?")
comma = pars.Literal(",")

total = pars.OneOrMore(
    pars.Group(
        pars.OneOrMore(dot)("dot")
        | pars.OneOrMore(question)("question")
    )
    + pars.Optional(comma)
)

result = total.parseString("...,?????,..,??")
所以一系列的点形成一个组,一系列的问号形成一个组。因此,我将这些组命名为
dot
question
。 然而,由此产生的词典

In: result.asDict()
Out: {}
如果我将其打印为
XML

<ITEM>
  <dot>
    <dot>.</dot>
    <ITEM>.</ITEM>
    <ITEM>.</ITEM>
  </dot>
  <ITEM>,</ITEM>
  <question>
    <question>?</question>
    <ITEM>?</ITEM>
    <ITEM>?</ITEM>
    <ITEM>?</ITEM>
    <ITEM>?</ITEM>
  </question>
  <ITEM>,</ITEM>
  <dot>
    <dot>.</dot>
    <ITEM>.</ITEM>
  </dot>
  <ITEM>,</ITEM>
  <question>
    <question>?</question>
    <ITEM>?</ITEM>
  </question>
</ITEM>

我通常不鼓励使用
asXML()
方法-它已被弃用,并且可能在2.2版中消失。如果改用
dump()
,您将看到您拥有的是一个命名组序列,而不是一个dict,因此只为键控值提供输出的
asDict()
,在顶层没有什么可处理的

print(result.dump())

[['.', '.', '.'], ',', ['?', '?', '?', '?', '?'], ',', ['.', '.'], ',', ['?', '?']]
[0]:
  ['.', '.', '.']
  - dot: ['.', '.', '.']
[1]:
  ,
[2]:
  ['?', '?', '?', '?', '?']
  - question: ['?', '?', '?', '?', '?']
[3]:
  ,
[4]:
  ['.', '.']
  - dot: ['.', '.']
[5]:
  ,
[6]:
  ['?', '?']
  - question: ['?', '?']
要获取每个解析的位,而不是调用
asDict()
asList()
,只需直接迭代结果。如果对每个列表元素调用
asDict()
,您将看到您的命名值:

for r in result:
    if isinstance(r, pars.ParseResults):
        print(r.asDict())

{'dot': ['.', '.', '.']}
{'question': ['?', '?', '?', '?', '?']}
{'dot': ['.', '.']}
{'question': ['?', '?']}
您还可以对这些子元素使用
getName()

for r in result:
    if isinstance(r, pars.ParseResults):
        print(r, r.getName())

['.', '.', '.'] dot
['?', '?', '?', '?', '?'] question
['.', '.'] dot
['?', '?'] question
编辑

也可考虑更换:

total = pars.OneOrMore(
    pars.Group(
        pars.OneOrMore(dot)("dot")
        | pars.OneOrMore(question)("question")
    )
    + pars.Optional(comma)
)

当您有一个由逗号分隔的事物列表时,逗号通常在解析时提供帮助,但在解析之后,您真正想要的只是事物
delimitedList
为您执行此操作(逗号是默认的分隔符,但您可以传递另一个分隔符作为可选的
delim
参数)

total = pars.OneOrMore(
    pars.Group(
        pars.OneOrMore(dot)("dot")
        | pars.OneOrMore(question)("question")
    )
    + pars.Optional(comma)
)
total = delimitedList(pars.Group(pars.OneOrMore(dot)("dot") | 
                                 pars.OneOrMore(question)("question"))))