加入pyparsing结果

问题描述 投票:2回答:1

我最近开始使用pyparsing,但坚持以下几点:列中的数据是组织的,其中列数未知,此外,此部分可能在输入中多次出现。例如,请参见下面的代码。

# -*- coding: utf-8 -*-

from pyparsing import *
from decimal import Decimal

def convert_float(a):
    return Decimal(a[0].replace(',','.'))

def convert_int(a):
    return int(a[0])

NL = LineEnd().suppress()

dot = Literal('.')
dates = Combine(Word(nums,exact=2) + dot + Word(nums,exact=2) + dot + Word(nums,exact=4))
day_with_date = Word(alphas,exact=3).suppress() + dates

amount = ( Combine(OneOrMore(Word(nums)) + ',' + Word(nums),adjacent=False) + 
           Optional(Literal('EUR')).suppress() ).setParseAction(convert_float)
number = Word(nums).setParseAction(convert_int)

item_head = OneOrMore(Keyword('Item').suppress() + number)
item_det = Forward()
item_foot = Forward()

def defineColNumber(t):
    nbcols = len(t)#[0])
    item_det << Dict(Group(day_with_date('date') + Group(nbcols*amount)('data')))
    item_foot << Keyword('TOTAL').suppress() + Group(nbcols*amount)

sec = (item_head('it*').setParseAction(defineColNumber) + 
       Group(OneOrMore(item_det))('details*') + 
       item_foot('totals*'))

parser = OneOrMore(
             sec
         )
parser.ignore(NL)

out = """
                             Item 1             Item 2             Item 3
Sat 20.04.2013     3 126 375,00 EUR     115 297,00 EUR      67 830,00 EUR      
Fri 19.04.2013     1 641 019,20 EUR      82 476,00 EUR      48 759,00 EUR      
Thu 18.04.2013       548 481,10 EUR      46 383,00 EUR      29 810,00 EUR      
Wed 17.04.2013       397 396,70 EUR      42 712,00 EUR      26 812,00 EUR 
TOTAL              8 701 732,00 EUR   1 661 563,00 EUR   1 207 176,00 EUR

                             Item 4             Item 5
Sat 20.04.2013       126 375,00 EUR     215 297,00 EUR      
Fri 19.04.2013     2 641 019,20 EUR      32 476,00 EUR      
Thu 18.04.2013       548 481,10 EUR      56 383,00 EUR      
Wed 17.04.2013       397 396,70 EUR      42 712,00 EUR
TOTAL              2 701 732,00 EUR   1 663 563,00 EUR   

"""

p = parser.parseString(out, parseAll=True)
print p.dump()
print p.it
print p.details[0]['18.04.2013'].data[2]
print p.totals

例如,当前p。它看起来像[[1, 2, 3], [4, 5]]我需要的其他部分也是[1,2,3,4,5],所以我可以不用p.details[0]['18.04.2013'].data[2]来做p.details['18.04.2013'].data[2]

我没主意-是否可以通过一些简单的方式加入结果,或者我需要使用其他函数来更改ParseResults?

感谢您的帮助。

BTW-此代码在解析日期,金额等方面有意义吗?

python parsing pyparsing
1个回答
1
投票

这种表格式数据的解析是pyparsing编写的原始案例之一。恭喜您能够解析非平凡的输入文本!

而不是尝试进行任何不自然的分组或将扭曲的数据扭曲或组合到所需的数据结构中,而是在获取解析结果并建立一个新的摘要结构后,我将其遍历。 ll呼叫summary。我们实际上是将数据累积到此dict中,强烈建议在发现新键时使用defaultdict来简化摘要的初始化。

from collections import defaultdict
summary = defaultdict(dict)

查看p中返回的当前结构,您将获得项目标题和详细数据集,这些数据集和详细数据集将收集到命名结果itdetails中。我们可以将它们压缩在一起以获得每个部分的标题和数据。然后,对于明细中的每一行,我们将通过使用解析后的数据值压缩项目标题来决定明细值。然后,我们将更新由line.date键入的摘要值:

for items,details in zip(p.it,p.details):
    for line in details:
        summary[line.date[0]].update(dict(zip(items,line.data)))

完成!看看我们积累了哪些关键:

print summary.keys()

给予:

['20.04.2013', '18.04.2013', '17.04.2013', '19.04.2013']

打印为'18 .04.2013'累积的数据:

print summary['18.04.2013']

给予:

{1: Decimal('548481.10'), 2: Decimal('46383.00'), 3: Decimal('29810.00'), 4: Decimal('548481.10'), 5: Decimal('56383.00')}
© www.soinside.com 2019 - 2024. All rights reserved.