通常在 pyparsing 中展平返回的列表
Generally flatten returned lists in 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 喜欢这样:
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)
有了这个 class 我得到了想要的结果。 :-)
但是,如果我想加入序列 d1 + d2
,我该怎么办?:
d1 = pp.Word(pp.nums).setName("PART_D1")
d2 = pp.Word(pp.alphas).setName("PART_D2")
expr = (d1 + d2)('D')
当然我创建了一个新的 class AndJoined
并使用了 AndJoined(d1,d2)
,但是后来我失去了很好的符号 d1 + d2
.
有没有一种通用的方法可以使结果变平? 我当然可以在检索到 dict 后手动 外部 展平 ParseResult,但我怀疑有一种简单的方法可以表达这个 里面 pyparsing
...
最简单的就是写一个这样的小帮手:
joiner = lambda expr: expr.addParseAction(' '.join)
然后在语法中的任何位置插入 joiner
:
a_b_c = joiner(a + b + c | d + Optional(e))
只需确保传递给 joiner
的令牌只是单级令牌。如果它们是嵌套的,那么您可能需要一个扁平化例程,但这很容易通过将 joiner
写为:
joiner = lambda expr: expr.addParseAction(flatten, ' '.join)
这个解释起来有点冗长,所以请耐心等待:使用 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 喜欢这样:
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)
有了这个 class 我得到了想要的结果。 :-)
但是,如果我想加入序列 d1 + d2
,我该怎么办?:
d1 = pp.Word(pp.nums).setName("PART_D1")
d2 = pp.Word(pp.alphas).setName("PART_D2")
expr = (d1 + d2)('D')
当然我创建了一个新的 class AndJoined
并使用了 AndJoined(d1,d2)
,但是后来我失去了很好的符号 d1 + d2
.
有没有一种通用的方法可以使结果变平? 我当然可以在检索到 dict 后手动 外部 展平 ParseResult,但我怀疑有一种简单的方法可以表达这个 里面 pyparsing
...
最简单的就是写一个这样的小帮手:
joiner = lambda expr: expr.addParseAction(' '.join)
然后在语法中的任何位置插入 joiner
:
a_b_c = joiner(a + b + c | d + Optional(e))
只需确保传递给 joiner
的令牌只是单级令牌。如果它们是嵌套的,那么您可能需要一个扁平化例程,但这很容易通过将 joiner
写为:
joiner = lambda expr: expr.addParseAction(flatten, ' '.join)