【问题标题】:Remove special characters from csv file using python使用python从csv文件中删除特殊字符
【发布时间】:2025-11-29 11:25:01
【问题描述】:

似乎已经有一些关于这个话题的内容 (How to replace all those Special Characters with white spaces in python?),但我无法终生解决这个简单的任务。

我有一个包含 75 列和近 4000 行的 .CSV 文件。我需要用“_”替换所有“特殊字符”($ # & * 等)并写入一个新文件。到目前为止,这是我所拥有的:

import csv

input = open('C:/Temp/Data.csv', 'rb')
lines = csv.reader(input)
output = open('C:/Temp/Data_out1.csv', 'wb')
writer = csv.writer(output)

conversion = '-"/.$'
text =  input.read()
newtext = '_'
for c in text:
    newtext += '_' if c in conversion else c
    writer.writerow(c)

input.close()
output.close()

所有这一切都成功地将所有内容作为单列写入输出文件,产生超过 65K 行。此外,特殊字符仍然存在!

很抱歉提出多余的问题。 提前谢谢!

【问题讨论】:

    标签: python csv python-2.7


    【解决方案1】:

    我可能会做类似的事情

    import csv
    
    with open("special.csv", "rb") as infile, open("repaired.csv", "wb") as outfile:
        reader = csv.reader(infile)
        writer = csv.writer(outfile)
        conversion = set('_"/.$')
        for row in reader:
            newrow = [''.join('_' if c in conversion else c for c in entry) for entry in row]
            writer.writerow(newrow)
    

    转身

    $ cat special.csv
    th$s,2.3/,will-be
    fixed.,even.though,maybe
    some,"shoul""dn't",be
    

    (注意我有一个引用的值)成

    $ cat repaired.csv 
    th_s,2_3_,will-be
    fixed_,even_though,maybe
    some,shoul_dn't,be
    

    现在,您的代码正在将整个文本读入一大行:

    text =  input.read()
    

    _ 字符开始:

    newtext = '_'
    

    遍历text中的每个字符:

    for c in text:
    

    将更正后的字符添加到newtext(非常缓慢):

        newtext += '_' if c in conversion else c
    

    然后将原始字符(?)作为一列写入新的csv:

        writer.writerow(c)
    

    .. 这不太可能是你想要的。 :^)

    【讨论】:

    • 嗨,你能解释一下newrow = [''.join('_' if c in conversion else c for c in entry) for entry in row]这行代码是如何工作的吗?
    【解决方案2】:

    这似乎不需要特别处理 CSV(只要特殊字符不是您的列分隔符)。

    lines = []
    with open('C:/Temp/Data.csv', 'r') as input:
        lines = input.readlines()
    
    conversion = '-"/.$'
    newtext = '_'
    outputLines = []
    for line in lines:
        temp = line[:]
        for c in conversion:
            temp = temp.replace(c, newtext)
        outputLines.append(temp)
    
    with open('C:/Temp/Data_out1.csv', 'w') as output:
        for line in outputLines:
            output.write(line + "\n")
    

    【讨论】:

    • 我认为你的循环逻辑是错误的:每行都会输出len(conversion) 行,不是吗?
    【解决方案3】:

    除了@Nisan.H 指出的错误和@dckrooney 提出的有效观点之外,在这种情况下您可能不需要以特殊方式处理文件,因为它是一个 CSV 文件(但请参阅我的评论下方):

    1. writer.writerow() 应该采用一系列字符串,每个字符串都将用逗号分隔(参见here)。在您的情况下,您正在编写一个字符串。
    2. 此代码设置为以 两种 方式从“C:/Temp/Data.csv”读取 - 通过input 和通过lines,但它实际上只从input 读取(因此代码无论如何都不会将文件作为 CSV 文件处理)。
    3. 代码将字符附加到newtext 并写出该变量的每个版本。因此,newtext 的第一个版本长 1 个字符,第二个版本长 2 个字符,第三个版本长 3 个字符,依此类推。

    最后,鉴于 CSV 文件可以包含引号,实际上可能有必要将输入文件专门作为 CSV 处理,以避免替换您想要保留的引号,例如用于保护 CSV 文件字段中存在的逗号的引号。在这种情况下,需要单独处理 CSV 文件的每个字段,然后将每一行写入新的 CSV 文件。

    【讨论】:

    • 太棒了。这行得通!谢谢大家带我完成这个。
    • @Jenny:很高兴为您提供帮助。如果我是你,我会倾向于将 DSM 的答案打勾,因为它是最完整和最详细的。这也可以避免其他人看到这个问题并认为它尚未得到回答。
    【解决方案4】:

    不妨试试

    s = open('myfile.cv','r').read()
    
    chars = ('$','%','^','*') # etc
    for c in chars:
      s = '_'.join( s.split(c) )
    
    out_file = open('myfile_new.cv','w')
    out_file.write(s)
    out_file.close()
    

    【讨论】:

    • 如果你出于某种原因想写行,那么就在循环之后执行rows = s.split('\n')