通常在pyparsing中展平返回的列表

时间:2016-12-12 05:42:10

标签: python grammar text-parsing pyparsing

这个解释有点长,所以请跟我说: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}} ...

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)