2017-07-17 43 views
0

我试图重构在下面的解析表达式version_name在PyParsing,如何使用合并()与非默认joinString

In [1]: from pyparsing import * 

In [2]: version_code = "(" + Word(nums)("version_code") + ")" 

In [3]: version_name = OneOrMore(~version_code + Word(printables)).setParseActio 
    ...: n(lambda s,l,t: " ".join(t))("version_name") 

In [4]: expression = version_name + version_code 

In [5]: result = expression.parseString("1.0 beta (10)") 

In [6]: result.asDict() 
Out[6]: {'version_code': '10', 'version_name': '1.0 beta'} 

使用.setParseAction(lambda s,l,t: " ".join(t))的相反,我想用Combine() 。不过,如果我尝试用

In [7]: version_name = Combine(OneOrMore(~version_code + Word(printables)), join 
    ...: String=" ")("version_name") 

然后在重新运行测试,以取代version_name

In [8]: expression = version_name + version_code 

In [9]: result = expression.parseString("1.0 beta (10)") 

我得到一个

ParseException: Expected "(" (at char 4), (line:1, col:5) 

好像解析器与解析停止1.0之后的version_name,而不是1.0 beta之后。有没有办法用Combine()来重构它,使它仍然有效?

+1

'Combine'预计所有匹配的标记都是连续的,除非'adjacent = False'。请参阅https://pythonhosted.org/pyparsing/pyparsing.Combine-class.html – PaulMcG

+1

关于Combine在这个问题中的更多讨论:https://stackoverflow.com/questions/45090980/need-help-understanding-pyparsing-behaviour – PaulMcG

回答

0

继PaulMcG的评论,我在Combine()构造函数添加adjacent=False

In [1]: from pyparsing import * 

In [2]: version_code = "(" + Word(nums)("version_code") + ")" 

In [3]: version_name = Combine(OneOrMore(~version_code + Word(printables)), joinString=" ", adjacent=False)("version_name") 

In [4]: expression = version_name + version_code 

In [5]: result = expression.parseString("1.0 beta (10)") 

In [6]: result.asDict() 
Out[6]: {'version_code': '10', 'version_name': '1.0 beta'} 

version_name现在包含根据需要这两个词('1.0 beta')。