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

标签 python iterator pyparsing

我尝试在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

最佳答案

我通常不鼓励使用 asXML() 方法 - 它已被弃用,并且可能会在 2.2 版本中消失。如果您使用 dump() 代替,您将看到您拥有的是一系列命名组,而不是字典,因此 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 参数)。

关于python - pyparsing 检索动态长度字符串的结果键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42022316/

相关文章:

python - 为什么在顶层按住 'X' 按钮会停止执行 tkinter 中的主窗口?

python - 来自 Gimp 程序的 OpenCV Python 脚本 - 草/硬表面边缘检测

python - 使用全局时 '=' 上的语法无效

c++ - 检查模板参数是否为 std::vector<T>::iterator

ruby - 为什么 `for i in a` 不是惯用的 Ruby?

python - 使用 pyparsing 从字符串中获取所有数字作为列表

python - 抑制 rpy2 中的警告

c++ - cppitertools:如何结合 iter::enumerate 和 iter::filter?

python - pyparsing - 同一条语句的第二次执行抛出异常

python - pyparsing:命名结果?