修复CSV文件单列多余逗号的简便方法
解决CSV文件中地址列含多余逗号的解析问题
你的思路完全正确——通过给包含多余逗号的ADDRESS列添加双引号包裹,让CSV解析器(包括Excel)将引号内的逗号视为字段内容而非分隔符。以下是针对大型CSV文件的高效Python解决方案,无需一次性加载整个文件到内存:
核心实现代码
def find_nth_comma(s, n): count = 0 for idx, char in enumerate(s): if char == ',': count += 1 if count == n: return idx return -1 # 配置文件路径和列参数 INPUT_FILE = "你的输入CSV文件路径.csv" OUTPUT_FILE = "修复后的输出文件.csv" TARGET_COLUMN = 6 # ADDRESS是第6列(从1开始计数) TOTAL_COLUMNS = 10 # 总列数:rownum到food共10列 BEFORE_COMMAS = TARGET_COLUMN - 1 # 目标列前的分隔逗号数量 AFTER_COMMAS = TOTAL_COLUMNS - TARGET_COLUMN # 目标列后的分隔逗号数量 with open(INPUT_FILE, 'r', encoding='utf-8') as infile, open(OUTPUT_FILE, 'w', encoding='utf-8') as outfile: # 写入表头(表头无多余逗号,直接保留) header = infile.readline().strip() outfile.write(f"{header}\n") # 逐行处理数据行 for line in infile: line = line.strip() if not line: outfile.write("\n") continue # 定位目标列的起始逗号(第BEFORE_COMMAS个逗号) start_pos = find_nth_comma(line, BEFORE_COMMAS) if start_pos == -1: outfile.write(f"{line}\n") continue # 定位目标列的结束逗号(倒数第AFTER_COMMAS个逗号) reversed_line = line[::-1] end_rev_pos = find_nth_comma(reversed_line, AFTER_COMMAS) if end_rev_pos == -1: outfile.write(f"{line}\n") continue end_pos = len(line) - end_rev_pos - 1 # 拼接带引号的目标列 fixed_line = ( line[:start_pos + 1] + '"' + line[start_pos + 1:end_pos] + '"' + line[end_pos:] ) outfile.write(f"{fixed_line}\n") print(f"修复完成,结果已保存至 {OUTPUT_FILE}")
代码说明
find_nth_comma函数:精准定位字符串中第n个逗号的位置,不受逗号前后空格影响。- 逐行处理:针对大型CSV文件,采用逐行读写模式,避免内存溢出。
- 字段包裹逻辑:找到ADDRESS列的起始(第5个逗号后)和结束(倒数第4个逗号前)位置,用双引号包裹该列内容,确保解析器识别为单个字段。
- 容错处理:如果某行格式不符合预期(逗号数量不对),直接保留原行,避免程序中断。
使用方法
- 将代码中的
INPUT_FILE和OUTPUT_FILE替换为你的实际文件路径。 - 确认
TARGET_COLUMN和TOTAL_COLUMNS与你的CSV结构匹配(示例中ADDRESS是第6列,总列数10)。 - 运行代码,生成的输出文件可直接用Excel打开:导入时选择逗号作为分隔符,Excel会自动识别引号包裹的字段。
替代方案:正则表达式快速处理
如果你的CSV格式没有极端特殊情况(比如字段内包含双引号),也可以用正则表达式快速替换:
import re INPUT_FILE = "你的输入CSV文件路径.csv" OUTPUT_FILE = "修复后的输出文件.csv" pattern = r'^((?:.*?,){5})(.*?)((?:,.*?){4})$' replacement = r'\1"\2"\3' with open(INPUT_FILE, 'r', encoding='utf-8') as infile, open(OUTPUT_FILE, 'w', encoding='utf-8') as outfile: header = infile.readline() outfile.write(header) for line in infile: fixed_line = re.sub(pattern, replacement, line.strip()) outfile.write(f"{fixed_line}\n")
内容的提问来源于stack exchange,提问作者Mike Shepard
相关产品推荐
相关产品推荐

