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
相关产品推荐
相关产品推荐

