pandas.read_csv处理多空格混合分隔符应设sep=r"s+"、engine="python"、skipinitialspace=True;复杂场景需逐行切片或预处理;伪CSV需替换引号/转义;注释续行须流式清洗;编码须用chardet探测。

用 pandas.read_csv 处理多空格、混合分隔符的文本
标准 CSV 用逗号,但现实里常遇到靠空格对齐、多个空格当分隔、甚至空格+制表符混用的“类表格”文本。直接用 sep="," 肯定报错或错列。pandas.read_csv 的 sep 参数支持正则,关键在设成 r"s+" —— 它把任意长度的空白(空格、制表符、换行)全视作一个分隔符。
实操建议:
- 加
engine="python":默认 C 引擎不支持正则分隔符,必须显式切换 - 加
skipinitialspace=True:跳过每行开头的空格,避免首列多出空字符串 - 若首行是标题但含多余空格,加
names=...手动指定列名,绕过自动解析
示例:pd.read_csv("data.txt", sep=r"s+", engine="python", skipinitialspace=True)
用 csv.reader + re.split 控制字段切分逻辑
当正则 s+ 仍不够用——比如某列本身含空格(如姓名字段 "Zhang San"),而其他列严格靠对齐分隔——这时候得放弃全自动解析,改用逐行读取 + 精确切片。
立即学习“Python免费学习笔记(深入)”;
常见错误现象:用 split() 后字段数忽多忽少,因为没考虑字段内空格。
实操建议:
- 先用
re.split(r"(s{2,})", line)拆出“内容块”和“分隔空隙”,再按固定位置或空隙宽度判断是否为真实分隔 - 更稳的做法是用
line[0:10].strip(), line[10:25].strip(), ...按列宽硬切,适合固定宽度格式(Fortran 输出、日志对齐文本) - 别忘了
str.rstrip(" ")去行尾控制符,否则最后一列可能带换行
处理含引号嵌套、转义字符的“伪CSV”
有些文件标着 .csv,但字段用中文引号“”包裹,或用反斜杠转义空格(如 name with space),csv 模块默认只认英文双引号和 转义,直接读会崩。
实操建议:
- 先用
open(..., encoding="utf-8-sig")防止 BOM 导致首列乱码 - 对反斜杠转义空格:读入后用
line.replace("\ ", " ")预处理,再进csv.reader - 对中文引号:用
re.sub(r'“(.+?)”', r'""', line)替换成标准双引号,再交给csv解析
注意:替换必须非贪婪(+?),否则跨字段吞掉中间的“”
跳过注释行、合并续行、识别空行等预处理陷阱
怪异格式常混着注释(# 开头)、续行(末尾反斜杠 )、纯空行。如果没在 read_csv 前清理,pandas 可能把注释当数据,或把续行断成两行。
实操建议:
- 用生成器预处理文件流:
def clean_lines(f): for line in f: line = line.rstrip(); if not line or line.startswith("#"): continue; if line.endswith("\"): line = line[:-1] + next(f).rstrip(); yield line - 传给
pd.read_csv时用io.StringIO(" ".join(clean_lines(open(...)))),避免反复读文件 - 别依赖
comment="#":它只跳过整行注释,对col1 data # comment这种无效
最易被忽略的是编码隐式转换:Windows 记事本存的 ANSI 文件用 utf-8 打开会乱码,得先用 chardet 探测,再选对编码读取。


















