dir_path = 'D:/VSCodeWorkspace/ZZH/' filename = 'a.csv' with codecs.open(dir_path+filename, 'r',encoding='utf-8') as srcFile, codecs.open(dir_path+filename+ '.tmp', 'w',encoding='utf-8') as dstFile: fileReader = csv.reader(srcFile, delimiter=',') fileWriter = csv.writer(dstFile,quoting=csv.QUOTE_ALL,delimiter='\t') for d in list(fileReader): for ii,dd in enumerate(d): dd = dd.replace('\r\n',',') dd = dd.replace('\n\r',',') dd = dd.replace('\n',',') dd = dd.replace('\r',',') dd=dd.replace('\t',' ') d[ii] = dd fileWriter.writerow(d) dstFile.close() srcFile.close()
上面代码中的dd.replace不会起什么作用,对吗?
你的感觉是对的 👍
在你贴的代码里,这几行:
dd = dd.replace('\r\n', ',') dd = dd.replace('\n\r', ',') dd = dd.replace('\n', ',') dd = dd.replace('\r', ',') dd = dd.replace('\t', ' ') d[ii] = dd
确实 不会起什么作用,原因有两个:
1. csv.reader 已经帮你处理掉了行结束符
-
csv.reader(srcFile, delimiter=',')读取时会自动去掉\r、\n等换行符,它们不会作为字段内容传递进来。 -
所以正常情况下,
dd里已经不会有换行符\r、\n。 -
你对
dd做.replace('\n', ','),基本不会替换到任何东西。
2. \t 也不会出现(除非字段里本来就有制表符)
-
因为原始 CSV 的分隔符是
,,所以除非某个字段文本里真的有\t字符,否则dd.replace('\t',' ')也不会生效。
✅ 总结:
-
对
\r\n、\n、\r的replace几乎没有效果,因为csv.reader已经处理掉了行结束符。 -
对
\t的replace可能有效,但前提是 CSV 里的某个字段真的包含制表符。
👉 建议:如果你真正的目标是“清理掉字段里的换行符和制表符”,可以改成:
for d in fileReader: d = [field.replace('\r', ',') .replace('\n', ',') .replace('\t', ' ') for field in d] fileWriter.writerow(d)
更简洁,不用 enumerate。
要不要我帮你写一个更“正统”的 CSV 清洗脚本,能同时解决编码、换行、分隔符等问题?
You said:
ChatGPT said:
好的 👍 我给你写一个更“正统”的 CSV 清洗脚本,目标是:
-
自动处理文件编码(支持 UTF-8 / GBK 等);
-
保证不会因为换行符或制表符而破坏 CSV 格式;
-
输入是 逗号分隔的 CSV,输出是 制表符分隔并且所有字段带引号的 CSV。
📝 示例代码(推荐用 pathlib 来管理路径)
import csv from pathlib import Path # 输入输出文件 dir_path = Path("D:/VSCodeWorkspace/ZZH") src_file = dir_path / "a.csv" dst_file = dir_path / "a.csv.tmp" # 打开文件,推荐用内置 open 而不是 codecs.open # newline='' 非常重要,避免 csv.writer 重复写入换行 with open(src_file, 'r', encoding='utf-8', newline='') as f_in, \ open(dst_file, 'w', encoding='utf-8', newline='') as f_out: reader = csv.reader(f_in, delimiter=',') writer = csv.writer(f_out, delimiter='\t', quoting=csv.QUOTE_ALL) for row in reader: # 清洗字段:去掉内部换行符、替换制表符 cleaned = [ field.replace('\r', ',') .replace('\n', ',') .replace('\t', ' ') for field in row ] writer.writerow(cleaned)
🚩 注意点
-
newline=''-
必须加在
open()里,否则csv.writer在 Windows 上会写出多余的空行。
-
-
编码
-
如果源文件不是 UTF-8(比如 GBK),可以改成:
with open(src_file, 'r', encoding='gbk', newline='') as f_in:
-
-
字段清洗
-
上面的代码确保任何字段里出现的
\r、\n都会被替换成逗号,,
制表符\t会被替换为空格。
-
👉 这样处理之后,你得到的 a.csv.tmp 文件就是 制表符分隔,字段全加引号,干净整齐。
要不要我帮你扩展一下,加上 自动检测文件编码 的功能(用 chardet),这样就不用自己猜是 UTF-8 还是 GBK?
You said:
ChatGPT said:
不客气 😄 下面我帮你把 自动检测编码 的功能也加上,这样你就不用手动去猜文件到底是 UTF-8、GBK 还是别的编码了。
📝 最终清洗脚本(带编码检测)
import csv from pathlib import Path import chardet # 输入输出文件路径 dir_path = Path("D:/VSCodeWorkspace/ZZH") src_file = dir_path / "a.csv" dst_file = dir_path / "a.csv.tmp" # 1. 先用二进制方式读取一部分文件,检测编码 with open(src_file, 'rb') as f: raw_data = f.read(50000) # 取前 50KB 足够判断 result = chardet.detect(raw_data) encoding = result["encoding"] or "utf-8" confidence = result["confidence"] print(f"[*] Detected encoding: {encoding} (confidence={confidence:.2f})") # 2. 用检测到的编码打开源文件,写入新文件 with open(src_file, 'r', encoding=encoding, newline='') as f_in, \ open(dst_file, 'w', encoding='utf-8', newline='') as f_out: reader = csv.reader(f_in, delimiter=',') writer = csv.writer(f_out, delimiter='\t', quoting=csv.QUOTE_ALL) for row in reader: # 清洗字段:换行符替换成逗号,制表符替换成空格 cleaned = [ field.replace('\r', ',') .replace('\n', ',') .replace('\t', ' ') for field in row ] writer.writerow(cleaned) print(f"[*] Cleaned file written to: {dst_file}")
🚀 特点
-
自动检测文件编码
-
用
chardet检测,常见的 UTF-8、GBK、GB2312、ISO-8859-1 等都能识别。 -
如果检测失败,就默认用 UTF-8。
-
-
统一输出 UTF-8 文件
-
即使源文件是 GBK 编码,最后得到的
.tmp文件也是 UTF-8 编码,更通用。
-
-
字段清洗规则
-
把字段里的
\r、\n→ 逗号, -
把
\t→ 空格' ' -
防止字段里的换行符破坏 CSV 格式。
-
👉 建议你第一次运行时,观察 print 出来的 Detected encoding: ... 是否符合预期。
要不要我再帮你写一个小函数,把这个逻辑封装成 clean_csv(src, dst),以后可以直接复用?
You said:
ChatGPT said:
太好了 👍 我帮你把逻辑封装成一个可复用的函数 clean_csv(src, dst),这样以后清理任何 CSV 文件都能直接调用。
📝 封装好的函数
import csv from pathlib import Path import chardet def clean_csv(src, dst, src_delimiter=',', dst_delimiter='\t'): """ 清理 CSV 文件: - 自动检测输入文件编码 - 替换字段内的换行符(\r,\n)为逗号 - 替换字段内的制表符(\t)为空格 - 输出为 UTF-8 编码,字段全部带引号 参数: src (str|Path): 输入文件路径 dst (str|Path): 输出文件路径 src_delimiter (str): 输入文件的分隔符,默认逗号 dst_delimiter (str): 输出文件的分隔符,默认制表符 """ src = Path(src) dst = Path(dst) # 1. 自动检测编码 with open(src, 'rb') as f: raw_data = f.read(50000) # 取前 50KB 足够判断 result = chardet.detect(raw_data) encoding = result["encoding"] or "utf-8" confidence = result["confidence"] print(f"[*] Detected encoding for {src.name}: {encoding} (confidence={confidence:.2f})") # 2. 按检测到的编码读取,统一输出 UTF-8 with open(src, 'r', encoding=encoding, newline='') as f_in, \ open(dst, 'w', encoding='utf-8', newline='') as f_out: reader = csv.reader(f_in, delimiter=src_delimiter) writer = csv.writer(f_out, delimiter=dst_delimiter, quoting=csv.QUOTE_ALL) for row in reader: cleaned = [ field.replace('\r', ',') .replace('\n', ',') .replace('\t', ' ') for field in row ] writer.writerow(cleaned) print(f"[*] Cleaned file written to: {dst}")
🚀 使用示例
# 假设你的文件路径 src_file = "D:/VSCodeWorkspace/ZZH/a.csv" dst_file = "D:/VSCodeWorkspace/ZZH/a.csv.tmp" # 调用函数 clean_csv(src_file, dst_file)
这样就能得到一个 干净的、UTF-8 编码的、制表符分隔并且带引号 的 CSV 文件。

浙公网安备 33010602011771号