这个解释有点长,所以请跟我说:pyparsing
我必须分析许多文字部分,如:
first multi segment part 123 45 67890 third multi segment part
------------^----------- -----^------ ------------^-----------
Part A: alpha words B: num words Part C: alpha words
我尝试为每个部分使用pp.OneOrMore
:
a = pp.OneOrMore(pp.Word(pp.alphas)).setName("PART_A")('A')
b = pp.OneOrMore(pp.Word(pp.nums)).setName("PART_B")('B')
c = pp.OneOrMore(pp.Word(pp.alphas)).setName("PART_C")('C')
expr = a + b + c
当我在字符串"first multi segment part 123 45 67890 third multi segment part"
上运行时,我得到了
- A: ['first', 'multi', 'segment', 'part']
- B: ['123', '45', '67890']
- C: ['third', 'multi', 'segment', 'part']
但是,我希望将所有结果展平为:
- A: 'first multi segment part'
- B: '123 45 67890'
- C: 'third multi segment part'
为此,我可以使用setParseAction
功能。因为我将使用这个功能有很多构造我扩展了OneOrMore
类喜欢这个:
class OneOrMoreJoined(pp.OneOrMore):
"""OneOrMore with results joined to one string"""
def __init__( self, expr, stopOn=None, joinString=' '):
super(OneOrMoreJoined,self).__init__(expr, stopOn=stopOn)
self.setParseAction(joinString.join)
通过这门课,我得到了理想的结果。 : - )
但是,如果我想要加入序列d1 + d2
,我该怎么办?:
d1 = pp.Word(pp.nums).setName("PART_D1")
d2 = pp.Word(pp.alphas).setName("PART_D2")
expr = (d1 + d2)('D')
当然我创建了一个新的课程AndJoined
并使用AndJoined(d1,d2)
,但后来我松开了好的符号d1 + d2
。
是否有通用的方法来平息结果? 我在检索字典后,当然可以在之外手动压缩ParseResult ,但我怀疑有一种简单的方法来表达里面的 {{ 1}} ...
答案 0 :(得分:1)
最简单的是写一个像这样的小帮手:
joiner = lambda expr: expr.addParseAction(' '.join)
然后在语法中插入joiner
:
a_b_c = joiner(a + b + c | d + Optional(e))
确保传递给joiner
的令牌只是单级令牌。如果它们是嵌套的,那么您可能需要一个flattener例程,但可以通过将joiner
写为:
joiner = lambda expr: expr.addParseAction(flatten, ' '.join)