【问题标题】:Parsing a series of fixed-width files [closed]解析一系列固定宽度的文件[关闭]
【发布时间】:2025-11-24 08:55:01
【问题描述】:

我有一系列(约 30 个)文件,这些文件由以下行组成:

xxxnnxxxxxxnnnnnnnnxxxnn

其中 x 是一个字符,n 是一个数字,每个组是一个不同的字段。

这对于每个文件都是固定的,因此很容易使用结构或切片进行拆分和读取;但是我想知道是否有一种有效的方法来处理大量文件(每个文件具有不同的字段和长度),而无需对其进行硬编码。

我的一个想法是为每个文件创建一个带有架构的 XML 文件,然后我可以在需要的地方动态添加新的,并且代码会更便携,但是我想检查没有更简单/更标准的方法这样做。

如果有帮助,我会将数据输出到 Redis 或 ORM 中,并且每个文件只会被处理一次(尽管稍后会添加具有不同结构的其他文件)。

谢谢

【问题讨论】:

  • 我明白为什么这被标记为潜在重复,但问题不在于解析 1 个文件,而在于解析很多具有不同结构的文件并制作非硬编码的可移植解决方案每一个。

标签: python parsing schema


【解决方案1】:

您可以使用itertools.groupby,例如str.isdigit(或isalpha):

>>> line = "aaa111bbb22cccc345defgh67"
>>> [''.join(i[1]) for i in itertools.groupby(line,str.isdigit)]
['aaa', '111', 'bbb', '22', 'cccc', '345', 'defgh', '67']

【讨论】:

    【解决方案2】:

    我认为@fredtantini 的回答包含了一个很好的建议——这是一种将其应用于您的问题的充实方式,以及my answer 中代码的微小变化,以解决一个名为 Efficient way of parsing fixed 的相关问题Python 中的宽度文件

    from itertools import groupby
    from struct import Struct
    isdigit = str.isdigit
    
    def parse_fields(filename):
        with open(filename) as file:
            # determine the layout of fields from the first line of the file
            firstline = file.readline().rstrip()
            fieldwidths = (len(''.join(i[1])) for i in groupby(firstline, isdigit))
            fmtstring = ''.join('{}s'.format(fw) for fw in fieldwidths)
            parse = Struct(fmtstring).unpack_from
            file.seek(0)  # rewind
            for line in file:
                yield parse(line)
    
    for row in parse_fields('somefile.txt'):
        print(row)
    

    【讨论】: