You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas读取含特殊引号与列内分隔符的CSV解析问题

解决Pandas读取含特殊引号与列内逗号的CSV时保留原始格式的问题

我有一个CSV文件,要求Pandas仅保留主动修改的字段,其余内容完全保留原始格式。文件以逗号(,)为分隔符,包含以下数据场景:

  • 无引号数据,如plah、blah
  • 任意数量和顺序的引号,如"plah"、""plah、"""plah"、""pl""ah""
  • 带引号包裹的列内逗号,如"plah,blah"、""plah"",""blah"

需要Pandas保留所有引号,且不将列内逗号识别为分隔符,但当前代码运行报错:

# Input file
csv_data = '''A,B,C,D,E
234,mno,C22,U,
567,pqr,"C3""",U,5555
999,abc,"C99",D,9999
678,bns,"C6,C7",F,6666
789,bcd,"""""C77,T,7777
'''

# Load CSV data into dataframes
df = pd.read_csv(StringIO(csv_data), header=0, dtype=str, keep_default_na=False, engine='python', sep=',', quoting=3)

df.to_csv('output.txt', sep=',', index=False, header=True, quoting=3)

运行时错误:

ParserError: Expected 5 fields in line 5, saw 6

期望输出与原输入完全一致:

A,B,C,D,E
234,mno,C22,U,
567,pqr,"C3""",U,5555
999,abc,"C99",D,9999
678,bns,"C6,C7",F,6666
789,bcd,"""""C77,T,7777

问题原因

原代码使用quoting=3(即csv.QUOTE_NONE),Pandas会将所有引号视为普通字符,但同时会把所有逗号当成字段分隔符——包括被引号包裹的列内逗号,导致字段数解析错误。

解决方案

使用正则表达式分隔符匹配不在引号内的逗号,确保只有字段间的逗号被用作分隔符,同时保留所有原始引号和列内内容;保存时继续使用quoting=3避免Pandas自动添加或修改引号。

修改后的代码:

import pandas as pd
from io import StringIO

csv_data = '''A,B,C,D,E
234,mno,C22,U,
567,pqr,"C3""",U,5555
999,abc,"C99",D,9999
678,bns,"C6,C7",F,6666
789,bcd,"""""C77,T,7777
'''

# 使用正则分隔符匹配不在引号内的逗号,确保正确拆分字段
df = pd.read_csv(
    StringIO(csv_data),
    header=0,
    dtype=str,
    keep_default_na=False,
    engine='python',  # 必须使用python引擎支持正则分隔符
    sep=r',(?=(?:[^"]*"[^"]*")*[^"]*$)'  # 正则:匹配后面跟偶数个引号的逗号(即不在引号内)
)

# 保存时禁用自动引号处理,完全保留原始内容
df.to_csv(
    'output.txt',
    sep=',',
    index=False,
    header=True,
    quoting=3,
    escapechar=None  # 避免转义引号
)

说明

  • 正则表达式,(?=(?:[^"]*"[^"]*")*[^"]*$)的作用是:仅匹配那些后面跟随偶数个引号的逗号,确保这些逗号是字段间的分隔符,而被引号包裹的列内逗号会被保留为字段内容。
  • 使用engine='python'是因为C引擎不支持正则分隔符。
  • quoting=3确保保存时Pandas不会自动添加或修改引号,完全保留原始字段内容。

内容的提问来源于stack exchange,提问作者SpaceyBot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 05:05:04