使用 setResultsName() 和 asXML() 进行 PyParsing 时标记错误
Tag error when PyParsing using setResultsName() and asXML()
我想使用 PyParsing 来解析文本并输出为 XML (asXML()
)。但是 XML 输出中的标签与 setResultsName
.
不一致
请看以下代码段:
p1 = (Literal('a').setResultsName('tag_a')).setResultsName('tag_out')
print(p1.parseString('a').asXML())
# Output:
# <tag_out>
# <tag_out>a</tag_out>
# </tag_out>
p2 = (Literal('a').setResultsName('tag_a') +
Literal('b').setResultsName('tag_b')).setResultsName('tag_out')
print((p2.parseString('a b').asXML()))
# The result is randomly chosen from these two outputs.
# <tag_out>
# <tag_a>a</tag_a>
# <tag_b>b</tag_b>
# </tag_out>
#
# <tag_out>
# <tag_out>a</tag_out>
# <tag_b>b</tag_b>
# </tag_out>
注意第一个内部元素的标签经常是错误的。
这是 PyParsing 的已知错误吗?
patch/workaround 是什么?
Pyparsing 不会根据您的代码自动为语法中的表达式赋予结构。这是设计使然,因此可以轻松地将部分表达式合并在一起,因此:
grammar = exprA + exprB + exprC
和
grammar = exprA + (exprB + exprC)
和
tmp = exprA + exprB
grammar = tmp + exprC
行为相同。因此,仅仅将 () 放在表达式周围并不会自动定义语法的另一个级别。
Pyparsing 提供了 Group
class 你想要的。如果您将代码更改为:
,您的结果将会大大改善
p1 = Group(Literal('a').setResultsName('tag_a')).setResultsName('tag_out')
print(p1.parseString('a').asXML())
p2 = Group(Literal('a').setResultsName('tag_a') +
Literal('b').setResultsName('tag_b')).setResultsName('tag_out')
print((p2.parseString('a b').asXML()))
话虽如此,asXML()
并不是 pyparsing 的最大部分,因为它必须在某些情况下在遍历结构和创建输出标签时进行猜测。如果这只是为了调试目的,我建议改用 dump()
方法。
我还建议您切换到 setResultsName
的隐式可调用形式 - 我认为它可以在不影响可读性的情况下简化您的语法代码。查看区别:
p1 = Group(Literal('a')('tag_a'))('tag_out')
print(p1.parseString('a').asXML())
p2 = Group(Literal('a')('tag_a') + Literal('b')('tag_b'))('tag_out')
print((p2.parseString('a b').asXML()))
我想使用 PyParsing 来解析文本并输出为 XML (asXML()
)。但是 XML 输出中的标签与 setResultsName
.
请看以下代码段:
p1 = (Literal('a').setResultsName('tag_a')).setResultsName('tag_out')
print(p1.parseString('a').asXML())
# Output:
# <tag_out>
# <tag_out>a</tag_out>
# </tag_out>
p2 = (Literal('a').setResultsName('tag_a') +
Literal('b').setResultsName('tag_b')).setResultsName('tag_out')
print((p2.parseString('a b').asXML()))
# The result is randomly chosen from these two outputs.
# <tag_out>
# <tag_a>a</tag_a>
# <tag_b>b</tag_b>
# </tag_out>
#
# <tag_out>
# <tag_out>a</tag_out>
# <tag_b>b</tag_b>
# </tag_out>
注意第一个内部元素的标签经常是错误的。
这是 PyParsing 的已知错误吗? patch/workaround 是什么?
Pyparsing 不会根据您的代码自动为语法中的表达式赋予结构。这是设计使然,因此可以轻松地将部分表达式合并在一起,因此:
grammar = exprA + exprB + exprC
和
grammar = exprA + (exprB + exprC)
和
tmp = exprA + exprB
grammar = tmp + exprC
行为相同。因此,仅仅将 () 放在表达式周围并不会自动定义语法的另一个级别。
Pyparsing 提供了 Group
class 你想要的。如果您将代码更改为:
p1 = Group(Literal('a').setResultsName('tag_a')).setResultsName('tag_out')
print(p1.parseString('a').asXML())
p2 = Group(Literal('a').setResultsName('tag_a') +
Literal('b').setResultsName('tag_b')).setResultsName('tag_out')
print((p2.parseString('a b').asXML()))
话虽如此,asXML()
并不是 pyparsing 的最大部分,因为它必须在某些情况下在遍历结构和创建输出标签时进行猜测。如果这只是为了调试目的,我建议改用 dump()
方法。
我还建议您切换到 setResultsName
的隐式可调用形式 - 我认为它可以在不影响可读性的情况下简化您的语法代码。查看区别:
p1 = Group(Literal('a')('tag_a'))('tag_out')
print(p1.parseString('a').asXML())
p2 = Group(Literal('a')('tag_a') + Literal('b')('tag_b'))('tag_out')
print((p2.parseString('a b').asXML()))