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

如何用Python 3解析包含嵌入换行符的CSV文件?

处理含单元格内换行的CSV文件解决方案

这个问题确实挺头疼的,尤其是从Excel/LibreOffice导出CSV时,单元格里的换行会变成字面的换行符,很容易让Python标准csv模块误判行边界。不过别慌,有几个实用的办法能解决:

方案1:正确配置标准csv模块参数

其实标准库不是不能处理,只是需要把参数配置对!因为办公软件导出的CSV通常会把带换行、逗号这类特殊字符的单元格用双引号括起来,只要告诉csv.reader识别这种引号包裹的内容,它就不会把里面的换行当成行结束。

试试这段代码:

import csv

# 注意要设置newline='',这是csv模块文档推荐的写法,避免自动转换换行符
with open('your_data.csv', 'r', newline='', encoding='utf-8') as f:
    # quotechar指定引号类型,quoting设置为QUOTE_ALL表示所有被引号包裹的内容都作为单元格
    reader = csv.reader(f, quotechar='"', quoting=csv.QUOTE_ALL)
    for row in reader:
        print(row)

如果你的CSV里只有部分单元格被引号包裹,也可以把quoting改成csv.QUOTE_MINIMAL,它会自动识别包含特殊字符的单元格。

方案2:用Pandas一键解决

如果项目里已经在用Pandas,那这事就更简单了——pd.read_csv默认就能正确解析带单元格内换行的CSV,完全不用手动调参数:

import pandas as pd

df = pd.read_csv('your_data.csv')
# 查看数据,单元格内的换行会被保留在对应字段里
print(df)

Pandas在处理这类CSV时会自动识别引号包裹的内容,把里面的换行当成单元格的一部分,非常省心,适合处理大型数据集。

方案3:手动解析(适合底层需求)

要是你不想依赖第三方库,也可以自己写逻辑来处理核心问题:判断当前是否处于引号包裹的状态,如果是,就把后续的行拼接到当前单元格里,直到遇到闭合的引号。

给你个参考实现:

def parse_csv_with_internal_newlines(file_path):
    rows = []
    current_row = []
    in_quotes = False
    current_cell = []

    with open(file_path, 'r', encoding='utf-8') as f:
        for line in f:
            # 先去掉行尾的换行符,单元格内的换行后面再加回来
            stripped_line = line.rstrip('\r\n')
            idx = 0
            while idx < len(stripped_line):
                char = stripped_line[idx]
                if char == '"':
                    # 切换引号状态
                    in_quotes = not in_quotes
                    idx += 1
                elif char == ',' and not in_quotes:
                    # 遇到分隔符且不在引号内,结束当前单元格
                    current_row.append(''.join(current_cell))
                    current_cell = []
                    idx += 1
                else:
                    current_cell.append(char)
                    idx += 1
            # 处理完当前行后,判断是否还在引号里
            if not in_quotes:
                # 行结束,把最后一个单元格加入行,再把行加入结果
                current_row.append(''.join(current_cell))
                rows.append(current_row)
                current_row = []
                current_cell = []
            else:
                # 还在引号内,说明当前行没结束,给单元格加个换行
                current_cell.append('\n')
    # 处理最后可能剩余的未完成行
    if current_row or current_cell:
        current_row.append(''.join(current_cell))
        rows.append(current_row)
    return rows

# 使用示例
parsed_data = parse_csv_with_internal_newlines('your_data.csv')
for row in parsed_data:
    print(row)

这个方法比较底层,适合需要自定义解析逻辑的场景,但日常用的话还是前两种更高效。

补充一句:文档里说的“读取器被硬编码为识别'\r'或'\n'作为行尾,忽略lineterminator”,其实是指它会自动判断行结束符,但引号包裹范围内的换行是不会被当作行结束的——只要配置对quotechar和quoting参数,标准库完全能处理这种情况~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:05:11