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

2024-04-20 14:02:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图解析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("...,?????,..,??")

所以一系列的点组成一个组,一系列的问号组成一个组。因此,我将这些组命名为dotquestion。 然而,最终的字典

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>

除了子项的奇怪命名外,组标记的名称也正确。我的问题是,如何在不使用xml的情况下迭代这个结果。我的意思是,.asList()删除键,.asDict()丢弃多个相同类型的项,.asXML()返回一个字符串。有没有一种方法可以像这样获得所有元组:

for k,v in GETMYTUPLES:
    print k, v
    -> dot [".", ".", "."]
    -> question ["?", ... and so forth

Tags: 类型列表字典resultpyparsingitem命名dot
1条回答
网友
1楼 · 发布于 2024-04-20 14:02:38

我通常不鼓励使用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)
)

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

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

相关问题 更多 >