匹配括号与OneOrMore

时间:2015-07-21 03:42:06

标签: python pyparsing

在我正在开发的应用程序中,我们有一个将某些字符组合在一起的DSL,它们可以分组或不分组。括号确定组。例如,良好的输入:

123
12(34)
1(234)

输入错误:

12(34

基本上我希望任何不匹配的括号根本不解析,因为这应该是出于我正在做的目的的语法错误。我制作了这个MVCE,用我的pyparsing代码显示了我遇到的问题:

import pyparsing as pp

def Syntax():
    lpar = pp.Literal('(').suppress()
    rpar = pp.Literal(')').suppress()
    rank = pp.Word('12345678', exact=1) #card ranking
    ranks = pp.OneOrMore(rank)
    rank_grouping = pp.Group(lpar + ranks + rpar)
    atom = ranks | rank_grouping
    return pp.OneOrMore(atom)

mvce_parser = Syntax()
try:
    mvce_parser.parseString("(76)(54")
except pp.ParseException:
    print("Exception1 was thrown!")
else:
    print("Exception1 not thrown :(")

try:
    mvce_parser.parseString("(76(54)")
except pp.ParseException:
    print("Exception2 was thrown!")
else:
    print("Exception2 not thrown :(")

输出:

$ python test.py 
Exception1 not thrown :(
Exception2 was thrown!

我在这里遇到的问题是第一个示例字符串(76)(54在这里解析并返回[['7','6']]但不会抛出我想要的ParseException。然而,第二个确实按预期失败了。

我怀疑这是OneOrMore抑制剩余部分的异常然后返回到目前为止的结果。

如何更改代码以避免此不一致问题?尽管OneOrMore很方便,但还是有其他方法可以不使用OneOrMore吗?

1 个答案:

答案 0 :(得分:3)

所以你要解析整个字符串。

要执行此操作,您需要在语法中明确添加StringEnd()

return pp.OneOrMore(atom) + pp.FollowedBy(pp.StringEnd())

或使用parseString参数

提供parseAll = True来电
mvce_parser.parseString("(76)(54", parseAll=True)