pyparsing 检索动态长度字符串的结果键
pyparsing retrieve resulting keys for strings of dynamic length
我尝试解析 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>
除了子项目的奇怪命名外,组标签的名称是正确的。我的问题是,如何在不使用此 xml 的情况下迭代此结果。我的意思是,.asList()
丢弃键,.asDict()
丢弃相同类型的多个项目和 .asXML()
returns 一个字符串。有没有办法像这样获取所有元组:
for k,v in GETMYTUPLES:
print k, v
-> dot [".", ".", "."]
-> question ["?", ... and so forth
我通常不鼓励使用 asXML()
方法 - 它已被弃用,可能会在 2.2 版中消失。如果您改用 dump()
,您将看到您拥有的是一系列命名组,而不是字典,因此 asDict()
仅提供键控值的输出,与 at 无关顶层。
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
参数)。
我尝试解析 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>
除了子项目的奇怪命名外,组标签的名称是正确的。我的问题是,如何在不使用此 xml 的情况下迭代此结果。我的意思是,.asList()
丢弃键,.asDict()
丢弃相同类型的多个项目和 .asXML()
returns 一个字符串。有没有办法像这样获取所有元组:
for k,v in GETMYTUPLES:
print k, v
-> dot [".", ".", "."]
-> question ["?", ... and so forth
我通常不鼓励使用 asXML()
方法 - 它已被弃用,可能会在 2.2 版中消失。如果您改用 dump()
,您将看到您拥有的是一系列命名组,而不是字典,因此 asDict()
仅提供键控值的输出,与 at 无关顶层。
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
参数)。