首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >连接pyparsing结果

连接pyparsing结果
EN

Stack Overflow用户
提问于 2013-06-07 19:11:49
回答 1查看 267关注 0票数 2

我最近开始使用pyparsing,我坚持如下:有一些数据是按列组织的,其中列的数量是未知的,另外,这样的部分在输入中可能会多次出现。请看下面的代码示例。

代码语言:javascript
复制
# -*- 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.it看起来像[[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?

谢谢你的帮助。

顺便说一句,这段代码对解析日期、金额等有意义吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-06-07 20:49:38

这种对表格数据的解析是编写pyparsing的初衷之一。恭喜你在解析非平凡的输入文本方面走到了这一步!

我不会尝试进行任何不自然的分组,也不会尝试将解析后的数据扭曲或组合到您想要的数据结构中,我只需要遍历解析后的结果,然后构建一个新的摘要结构,我称之为summary。我们实际上要将数据累积到这个字典中,这强烈建议在找到新的关键字时使用默认字典来简化摘要的初始化。

代码语言:javascript
复制
from collections import defaultdict
summary = defaultdict(dict)

查看p中返回的当前结构,您将获得收集到命名结果itdetails中的项头和详细数据集。我们可以将它们压缩在一起,以获得每个部分的标题和数据。然后,对于详细信息中的每一行,我们将通过使用解析的数据值压缩项标题来创建详细值的字典。然后,我们将更新由line.date键入的汇总值

代码语言:javascript
复制
for items,details in zip(p.it,p.details):
    for line in details:
        summary[line.date[0]].update(dict(zip(items,line.data)))

完成了!看看我们积累的关键字是什么:

代码语言:javascript
复制
print summary.keys()

提供:

代码语言:javascript
复制
['20.04.2013', '18.04.2013', '17.04.2013', '19.04.2013']

打印‘18.04.2013’的累计数据:

代码语言:javascript
复制
print summary['18.04.2013']

提供:

代码语言:javascript
复制
{1: Decimal('548481.10'), 2: Decimal('46383.00'), 3: Decimal('29810.00'), 4: Decimal('548481.10'), 5: Decimal('56383.00')}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16982712

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档