如何更改奇怪的CSV分隔符?

时间:2016-12-11 11:16:21

标签: python csv

我有一个CSV文件,我无法在Excel中打开。

CSV分隔符为|~|,并且在行的末尾为|~~|

我有一些示例数据:

Education|~|Name_Dutch|~|Name_English|~|Faculty|~~|International Business|~|MB|~|MB|~|ED|~~|

标题部分为:Education|~|Name_Dutch|~|Name_English|~|Faculty|~~|

数据/行部分为:International Business|~|MB|~|MB|~|ED|~~|

我需要了解如何使用Python脚本以正常的,逗号分隔值更改此CSV文件。

4 个答案:

答案 0 :(得分:0)

您可以协助内置的csv模块+ string.split()功能:

import csv

content = """Education|~|Name_Dutch|~|Name_English|~|Faculty|~~|International Business|~|MB|~|MB|~|ED|~~|"""

# Or read it's content from a file 

with open('output.csv', 'w+') as f:
    writer = csv.writer(f)
    lines = content.split('|~~|')
    for line in lines:
        csv_row = line.split('|~|')
        writer.writerow(csv_row)

它将输出名为output.csv

的文件
Education,Name_Dutch,Name_English,Faculty
International Business,MB,MB,ED
""

在处理csv文件时,我更倾向于使用csv模块而不是.replace('|~|', ','),因为csv模块具有对{{1}等特殊字符的内置支持}}

答案 1 :(得分:0)

你提到的自定义分隔符似乎足够独特,所以你可以在它们上面做一个string.replace。然后写出文件。 读写部分包含您需要的所有详细信息。 https://docs.python.org/2/tutorial/inputoutput.html

答案 2 :(得分:0)

import csv

in_name = 'your_input_name.csv'
outname = 'your_outpt_name.csv'

with open(in_name, newline='') as csvfile:
    csvreader = csv.reader(csvfile, delimiter='~', quotechar='|')
    with open(outname, "w", newline='') as outfile:
        csvwriter = csv.writer(outfile, quotechar='"', quoting=csv.QUOTE_NONNUMERIC)
        for row in csvreader:
            line = []
            for item in row:
                if item != "":
                    line.append(item)
                else:
                    csvwriter.writerow(line)
                    line = []

由于csv.reader无法将"~~"识别为行尾,因此会将其转换为"",因此对于csv.writer,我们会反复准备列表的一部分(从csv.reader获得,直到达到""

答案 3 :(得分:0)

如果文件很小,你只需将其全部内容读入内存并替换所有发现的奇怪分隔符,然后将其新版本写回。

但是,如果文件很大或者您只是想节省内存使用量,那么也可以逐步读取文件,一次读取一个字符,并完成需要完成的任务。

csvfile构造函数的csv.reader参数可以是任何支持迭代器协议的对象,并在每次调用next()方法时返回一个字符串。“

这意味着“对象”可以是生成器函数或生成器表达式。在下面的代码中,我实现了一个简单的FSM(Finite State Machine)来解析奇怪格式的文件,并检测它检测到的每一行输出yield。它可能看起来像很多代码,但操作非常简单,所以应该相对容易理解它是如何工作的:

import csv

def weird_file_reader(filename):
    """Generator that opens and produces "lines" read from the file while
       translating the sequences of '|~|' to ',' and '|~~|' to '\n' (newlines).
    """
    state = 0
    line = []
    with open(filename, 'rb') as weird_file:
        while True:
            ch = weird_file.read(1)  # read one character
            if not ch:  # end-of-file?
                if line:  # partial line read?
                    yield ''.join(line)
                break
            if state == 0:
                if ch == '|':
                    state = 1
                else:
                    line.append(ch)
                    #state = 0  # unnecessary
            elif state == 1:
                if ch == '~':
                    state = 2
                else:
                    line.append('|'+ch)
                    state = 0
            elif state == 2:
                if ch == '|':
                    line.append(',')
                    state = 0
                elif ch == '~':
                    state = 3
                else:
                    line.append('|~'+ch)
                    state = 0
            elif state == 3:
                if ch == '|':
                    line.append('\n')
                    yield ''.join(line)
                    line = []
                    state = 0
                else:
                    line.append('|~~'+ch)
                    state = 0
            else:
                raise RuntimeError("Can't happen")

with open('fixed.csv', 'wb') as outfile:
    reader = csv.reader((line for line in weird_file_reader('weird.csv')))
    writer = csv.writer(outfile)
    writer.writerows(reader)

print('done')