Python csv 模块读写含换行与逗号的字段:别再用 split 手动解析

举报
yd_217513249 发表于 2026/10/21 23:39:17 2026/10/21
【摘要】 CSV 字段中可能包含逗号、换行和双引号,手动 split 容易导致列错位。本文介绍 Python 标准库 csv 模块的正确读写方式,给出最小可运行示例,并说明 newline、编码、方言、大文件迭代等边界与限制。

用 csv 模块读写含换行与逗号的字段

问题场景

CSV 看起来简单,但字段里一旦出现逗号或换行,用 line.split(',') 就会错位。

例如数据文件 input.csv 内容如下:

id,name,note
1,example,comma,line one
line two

这里第二行本意可能是 id 为 1,name 为 example,comma,note 为两行文本。但因为没有引号,解析器无法区分字段内的逗号和换行。按行读取再 split(','),note 会被拆成两行,example 和 comma 也会被拆成两列,列数不一致,行就错位了。

手动 split 的局限

  • line.split(',') 无法区分字段分隔符和字段内容里的逗号。
  • 按行读取无法区分记录结束换行和字段内换行。
  • 引号内的转义双引号,例如两个连续双引号表示一个双引号,也无法正确还原。

因此,只要数据可能包含逗号、换行、双引号,就应交给标准库 csv 解析,而不是自己写切分逻辑。

用 csv.reader 读

关键点:打开文件时传 newline='',让 csv 模块自己处理换行。

import csv

with open('input.csv', 'r', encoding='utf-8', newline='') as f:
    reader = csv.reader(f)
    for row in reader:
        print(len(row), row)

reader 会正确处理带引号的字段:引号内的逗号保留在字段内,引号内的换行保留在字段内,两个连续双引号还原为一个双引号。

用 csv.writer 写

写入时不需要手动拼引号。csv.writer 会根据方言自动给需要转义的字段加引号。

import csv

rows = [
    ['id', 'name', 'note'],
    [1, 'example,comma', '''line one
line two'''],
    [2, 'plain', 'text'],
]

with open('output.csv', 'w', encoding='utf-8', newline='') as f:
    writer = csv.writer(f)
    writer.writerows(rows)

这里 note 字段中的换行会写成字段内的换行,example,comma 会因为含逗号而被双引号包裹。读取时可以还原成原来的字段。

最小可运行示例

将下面代码保存为 demo.py。代码先写入 output.csv,再读回并打印,便于观察字段是否保持完整。

import csv

def write_demo(path):
    rows = [
        ['id', 'name', 'note'],
        [1, 'example,comma', '''line one
line two'''],
        [2, 'plain', 'text'],
    ]
    with open(path, 'w', encoding='utf-8', newline='') as f:
        writer = csv.writer(f)
        writer.writerows(rows)

def read_demo(path):
    with open(path, 'r', encoding='utf-8', newline='') as f:
        reader = csv.reader(f)
        for row in reader:
            print(len(row), row)

if __name__ == '__main__':
    write_demo('output.csv')
    read_demo('output.csv')

运行方法:

python demo.py

输出中每行记录应有 3 个字段。第二行的 note 字段会是一个包含换行的字符串。注意 csv.reader 读出的字段都是字符串,数字 1 会变成 '1',需要业务层自行转换。

边界与限制

  1. 必须使用 newline='':这是官方文档推荐做法,避免在 Windows 等平台上出现多余空行或换行处理冲突。
  2. 编码要显式指定:csv 模块不负责编码。UTF-8 用 encoding='utf-8';如果文件带 BOM,可尝试 utf-8-sig。不要依赖系统默认编码。
  3. 方言不等于自动识别:默认是 excel 方言,逗号分隔、双引号包裹。TSV 可以设置 delimiter 为制表符;其它引号规则可设置 quotechar、quoting、escapechar。csv.Sniffer 可以猜测方言,但只适合小样本,猜测可能失败。
  4. 字段不会自动去空白:reader 不会去掉字段两侧空格。需要时可用 skipinitialspace=True,但不要无差别 strip(),否则可能改变真实数据。
  5. 大文件逐行迭代:for row in reader 是流式读取,不要写 list(reader) 一次性载入,除非确认内存足够。
  6. 写入换行符:writer 默认使用 CRLF。如果交换环境要求 LF,可以显式设置 lineterminator,但需确认接收方兼容。
  7. 公式注入与安全:csv 模块只负责格式,不负责安全。字段以等号、加号、减号、@ 开头时,导出给表格软件可能被当公式;需要自行加前缀或转义。
  8. 非字符串值:建议在写入前显式转换类型,避免依赖 writer 的隐式字符串化行为,这会让数据含义更清晰。

小结

字段中可能含逗号、换行、双引号时,不要手动 split。用 csv.reader 和 csv.writer 读写,并注意 newline=''、显式编码和方言设置。这样能避免行错位,也能让数据在常见 CSV 解析器之间保持兼容。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。