Python 3.5使用特殊字符解析csv

时间:2016-05-14 20:31:24

标签: python parsing csv character

我有一个文件,我想解析成一个csv。该文件是一个导出文件,并以下列格式到达我(逐行,每个文件包含数千行):

03:30:30  08:30:30 [15 August 2015] productid:123456789 manuf:987654321 case:12 pallet:1234 id:12 code:1234  12345  123  12

我想将数据放入csv文件中,如下所示:

local time, GMT time, date, product id, manuf id, case, pallet, id, code, company id, location, secondary code
03:30:30, 08:30:30, 15 August 2015, 123456789, 987654321, 12, 1234, 12, 1234, 12345, 123, 12

我已经成功完成了这项工作,但我相信使用了错误的工具。我一直在使用如下的行:

import fileinput
for line in fileinput.FileInput("file",inplace=1):
    line = line.replace(":",",")

import fileinput
for line in fileinput.FileInput("file",inplace=1):
    line = line.replace("case"," ")

给了我类似的东西..

l h, l min, ls, gmt h, gmt m, gmt s, date, product id, manuf id, case, pallet, id, code, company id, location, secondary code
03,30,30,08,30,30,15 August 2015, 123456789, 987654321, 12, 1234, 12, 1234, 12345, 123, 12

问题是:我必须使用连续的行将每个字符和单词解析为csv(描述符单词,冒号,括号等),并且在大型数据集上需要很长时间。此外,我将它全部保存到辅助文件而不是写入到位。通过用逗号替换冒号,我的时间被分解为单独的列。我已经花了几天玩不同的选项并且到达正则表达式,但是作为python的完整新手还没有提出解决方案。从逗号分隔的块重建时间到正确的格式可能更简单,但我不知所措。请协助。提前致谢。

编辑:

我试图实现Sparkeandshine以及Julian的可行解决方案版本。我最接近让Sparkeandshie的版本工作,但我只能迭代一行;实际上在解决方案中的那个,而不是整个文件。我花了最后24个尝试两种解决方案的不同迭代,但无济于事。我就是这样的地方:

#!/usr/bin/env python

import csv
import os

inputFileName = 'test.txt'
outputFileName = 'finished.csv'

with open(inputFileName, newline='') as inFile, open(outputFileName,    'w', newline='') as outfile:
    r = csv.reader(inFile)
    w = csv.writer(outfile)

    line = '03:30:30 08:30:30 [15 August 2015] productid:123456789 manuf:987654321 case:12 pallet:1234 id:12 code:1234 12345 123 12'
str_list = line.split()

new_list = [str_list[0],
        str_list[1],
        ' '.join([item.strip('[]') for item in str_list[2:5]]), # '[15', 'August', '2015]'
        str_list[6].split(':')[1],
        str_list[7].split(':')[1],
        str_list[8].split(':')[1],
        str_list[9].split(':')[1],
        str_list[10].split(':')[1],
        str_list[12],
        str_list[13]
        ]

with open(inputFileName, newline='') as inFile, open(outputFileName, 'w', newline='') as outfile:
    r = csv.reader(inFile)
    w = csv.writer(outfile)

    for row in r:
        w.writerow(new_list)

编辑:解决方案下面的Sparkandshines对于设置行很有用,但我发现我的一些数据有不同长度的行。例如,有时几行会短几个“列”数据,或者最后三列可能重复两次。为了解决这个问题,我一直在使用“尝试”和“除了错误,继续”可能的长度。使用这种方法,我在最终文件中得到重复的行;有没有更好的方法来使用Sparkandshine的解决方案与不同长度的线? ...或者更容易找到重复的行(通过检查/比较两个/三个列)并删除它们?

2 个答案:

答案 0 :(得分:1)

使用

处理每一行
line = '03:30:30 08:30:30 [15 August 2015] productid:123456789 manuf:987654321 case:12 pallet:1234 id:12 code:1234 12345 123 12'
str_list = line.split()

new_list = [str_list[0],
            str_list[1],
            ' '.join([item.strip('[]') for item in str_list[2:5]]), # '[15', 'August', '2015]'
            str_list[6].split(':')[1],
            str_list[7].split(':')[1],
            str_list[8].split(':')[1],
            str_list[9].split(':')[1],
            str_list[10].split(':')[1],
            str_list[12],
            str_list[13]
            ]

print(new_list)
# Output
['03:30:30', '08:30:30', '15 August 2015', '987654321', '12', '1234', '12', '1234', '123', '12']

使用

写入csv文件
with open(filename, 'w') as f:
    writer = csv.writer(f)

    # write the file header
    fieldnames = ['local time', 'GMT time', 'date', 'product id', 'manuf id', 
            'case', 'pallet', 'id', 'code', 'company id', 'location', 'secondary code']
    writer.writerow(fieldnames)

    # process each line
    for line in lines:
        new_list = do_something()

        writer.writerow(new_list) # write to the file

或处理所有行并将结果保存到列表列表中,然后转到带有writerows的csv文件,

writer.writerows(lists)

完整的源代码,

#!/usr/bin/env python
import csv

inputFileName = 'test.txt'
outputFileName = 'finished.csv'

with open(outputFileName, 'w') as outfile:
    w = csv.writer(outfile)

    # write the file header
    fieldnames = ['local time', 'GMT time', 'date', 'product id', 'manuf id', 
            'case', 'pallet', 'id', 'code', 'company id', 'location', 'secondary code']
    writer.writerow(fieldnames)


    # process each line
    with open(inputFileName, 'r') as inFile:
        for line in inFile:
            str_list = line.rstrip().split()
            new_list = [str_list[0],
                        str_list[1],
                        ' '.join([item.strip('[]') for item in str_list[2:5]]), # '[15', 'August', '2015]'
                        str_list[6].split(':')[1],
                        str_list[7].split(':')[1],
                        str_list[8].split(':')[1],
                        str_list[9].split(':')[1],
                        str_list[10].split(':')[1],
                        str_list[12],
                        str_list[13]]

            w.writerow(new_list) # write to the file

答案 1 :(得分:0)

如果您有一个已知的输入文件结构,则不需要使用正则表达式,因为它们较慢。对于您的情况,请尝试使用类似于以下代码的内容:

import csv
with open('destination.csv', 'w', newline='') as csvfile:
    csv_writer = csv.writer(csvfile, delimiter=',')
    ...  # get your data here, the next code is for one line of data
    values = line.split()
    values[2] = '{} {} {}'.format(values[2][1:], values[3], values[4][:-1])  # Get rid of square brackets
    for idx in range(5, 11):
        values[idx] = values[idx].split(':')[1]  # get the number values
    values.pop(3);  # remove separated month name
    values.pop(3);  # remove separated year

    csv_writer.writerow(values)

您只编辑需要它的数据,然后将整行写入csv。