使用Python编写/解析固定宽度的文件

Way*_*ina 11 python parsing edi

我是Python的新手,我正在使用它来编写供应商需要的一些毛茸茸的EDI.

基本上他们需要一个80个字符的固定宽度文本文件,该字段的某些"块"包含数据,而其他文件则留空.我有文档,所以我知道每个"块"的长度是多少.我得到的响应更容易解析,因为它已经有数据,我可以使用Python的"切片"来提取我需要的东西,但我无法分配到切片 - 我已经尝试过了,因为它听起来像一个好的解决方案,它不起作用,因为Python字符串是不可变的:)

就像我说我真的是Python的新手,但我很高兴学习它:)我会怎么做呢?理想情况下,我希望能够说范围10-20等于"Foo",并且它是带有7个额外空格字符的字符串"Foo"(假设所述字段的长度为10)并且具有80字符大字体的一部分,但我不知道如何做我正在思考的事情.

gim*_*mel 17

您不需要分配切片,只需使用构建字符串% formatting.

具有3个数据项的固定格式的示例:

>>> fmt="%4s%10s%10s"
>>> fmt % (1,"ONE",2)
'   1       ONE         2'
>>> 
Run Code Online (Sandbox Code Playgroud)

同样的事情,数据提供的字段宽度:

>>> fmt2 = "%*s%*s%*s"
>>> fmt2 % (4,1, 10,"ONE", 10,2)
'   1       ONE         2'
>>> 
Run Code Online (Sandbox Code Playgroud)

分离数据和字段宽度,以及使用zip()str.join()技巧:

>>> widths=(4,10,10)
>>> items=(1,"ONE",2)
>>> "".join("%*s" % i for i in zip(widths, items))
'   1       ONE         2'
>>> 
Run Code Online (Sandbox Code Playgroud)


Jar*_*die 8

希望我理解你在寻找什么:通过一个简单的变量方便地识别线的每个部分,但输出填充到正确的宽度?

下面的代码段可能会为您提供所需内容

class FixWidthFieldLine(object):

    fields = (('foo', 10),
              ('bar', 30),
              ('ooga', 30),
              ('booga', 10))

    def __init__(self):
        self.foo = ''
        self.bar = ''
        self.ooga = ''
        self.booga = ''

    def __str__(self):
        return ''.join([getattr(self, field_name).ljust(width) 
                        for field_name, width in self.fields])

f = FixWidthFieldLine()
f.foo = 'hi'
f.bar = 'joe'
f.ooga = 'howya'
f.booga = 'doin?'

print f
Run Code Online (Sandbox Code Playgroud)

这会产生:

hi        joe                           howya                         doing     
Run Code Online (Sandbox Code Playgroud)

它的工作原理是存储一个类级变量,fields该变量记录每个字段在输出中应出现的顺序,以及该字段应具有的列数.__init__最初将相应命名的实例变量设置为空字符串.

__str__方法将这些值输出为字符串.它使用对类级别fields属性的列表理解,按名称查找每个字段的实例值,然后根据列左对齐它的输出.然后,生成的字段列表由空字符串连接在一起.

请注意,这不会解析输入,但您可以轻松地覆盖构造函数以获取字符串并根据字段和字段宽度解析列fields.它也不会检查长度超过其分配宽度的实例值.


Nad*_*mli 8

您可以使用对齐函数左对齐,右对齐并将字符串置于给定宽度的字段中.

'hi'.ljust(10) -> 'hi        '
Run Code Online (Sandbox Code Playgroud)