我最近开始使用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-此代码在解析日期,金额等方面有意义吗?
这种表格式数据的解析是pyparsing编写的原始案例之一。恭喜您能够解析非平凡的输入文本!
而不是尝试进行任何不自然的分组或将扭曲的数据扭曲或组合到所需的数据结构中,而是在获取解析结果并建立一个新的摘要结构后,我将其遍历。 ll呼叫summary
。我们实际上是将数据累积到此dict中,强烈建议在发现新键时使用defaultdict来简化摘要的初始化。
from collections import defaultdict
summary = defaultdict(dict)
查看p
中返回的当前结构,您将获得项目标题和详细数据集,这些数据集和详细数据集将收集到命名结果it
和details
中。我们可以将它们压缩在一起以获得每个部分的标题和数据。然后,对于明细中的每一行,我们将通过使用解析后的数据值压缩项目标题来决定明细值。然后,我们将更新由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')}