Python读取CSV时全字段未加引号如何忽略引号内逗号
问题描述
读取CSV数据时,需要实现规则:即使引号不紧邻分隔符(如下方第2条记录),引号内的逗号也不能被识别为字段分隔符。
直接使用逗号作为分隔符解析时,第1、3条记录可正常解析,但第2条记录解析失败,尝试配置escapeCharacter参数没有生效。
测试数据
col1, col2, col3 a, b, c a, b1 "b2, b3" b4, c "a1, a2", b, c
解析结果对比
- 第2条记录预期解析结果:
ab1 "b2, b3" b4c
- 第2条记录实际错误解析结果:
ab1 "b2b3" b4
问题原因
所有标准CSV解析器的默认逻辑,都只会把紧贴字段前后分隔符的引号判定为字段包裹标记。你这份数据第2行里的双引号是字段内容的一部分,不属于字段包裹符,因此解析器会直接按逗号位置切分,自然会把引号内部的逗号当成分隔符。escapeCharacter参数的作用是转义「作为字段包裹符的引号」本身,处理的是包裹字段的引号需要出现在内容里的场景,根本管不到这种内嵌在内容里的非包裹引号,所以配置了也不会生效。
解决方法
不要直接用默认CSV解析参数硬读,先做一层预处理再解析:
- 逐行读取CSV原始文本,不要直接按逗号切分
- 遍历每行的每个字符,维护一个
in_quote状态标记:每遇到一个双引号就翻转一次状态 - 切分字段时,只有
in_quote为False状态下遇到的逗号,才判定为字段分隔符;in_quote为True状态下的逗号,临时替换成不会和正常内容冲突的占位符(比如%%COMMA%%) - 按分隔符切分出所有字段后,再把字段里的占位符替换回逗号,就能得到正确结果
如果用Python的pandas库读取,可以写个自定义的行解析器传入,或者先按上述逻辑把原始CSV处理成标准格式,再用常规read_csv方法读取即可。
内容的提问来源于stack exchange,提问作者Satya Alamanda
相关产品推荐
相关产品推荐

