正则表达式仅适用于小规模、格式不规范或临时修复的csv解析场景;标准做法应优先使用内置csv解析器(如php的str_getcsv()、python的csv.reader或pandas的read_csv()),因其已妥善处理引号、换行、转义等边界情况。

正则表达式可以解析 CSV 行,但只推荐用于小规模、格式不规范或需临时修复的场景;标准做法仍是优先使用内置函数(如 PHP 的 str_getcsv()、Python 的 csv.reader 或 Pandas 的 read_csv()),它们已妥善处理引号、换行、转义等边界情况。
理解 CSV 字段结构是写对正则的前提
CSV 单行由逗号分隔字段组成,字段可能:
- 不带引号:纯文本,不含逗号、换行、引号,例如
John - 带双引号包裹:允许含逗号、换行符、甚至内部双引号(用两个
""表示转义),例如"Doe, Jr."或"He said: ""Hi""\n"
简单用 explode(',', $line) 或 split(',') 会把引号内的逗号也拆开,导致错位。正则必须区分“分隔用的逗号”和“字段内容里的逗号”。
一个实用的 PHP 正则模式
匹配单行中每个字段(兼容引号与非引号):
Miller (mlr) 是一个命令行工具,用于查询、整形和重新格式化名称索引数据,如 CSV、TSV、JSON 和 JSON Lines。它将 awk、sed、cut、join 和 sort 的功能整合到一个专为结构化数据处理而构建的单一工具中。
-
"([^"]|"")*":匹配被双引号包围的内容,支持""转义 -
[^",\r\n]*:匹配不包含引号、逗号、换行的普通字段 -
,?:匹配字段后可选的逗号(最后一列无逗号) -
\s*:忽略字段前后的空白(增强鲁棒性)
使用时需手动清理结果:去掉首尾引号、将 "" 替换为 ",再 trim()。
Python 中更稳妥的替代方案
虽然可用 re.findall() 配合类似正则提取字段,但强烈建议:
- 用
csv.reader或str_getcsv()解析标准 CSV - 若首行是元数据(如
#001=xyz_0[1234]),单独读取首行 + 正则提取(如r'#(\d+)=(\w+_\d)\[(\d+)\]'),其余行交给pandas.read_csv(skiprows=1) - 遇到含换行字段时,先按完整记录读取(而非逐行),再用正则识别记录边界,或直接用
csv模块的QUOTE_ALL等参数控制行为
注意事项与避坑点
正则解析 CSV 容易踩的坑:
- 大文件性能差:正则回溯可能导致卡顿或栈溢出
- 无法自动处理跨多行字段:需额外逻辑合并上下文,极易出错
- 不兼容 RFC 4180 全部规则(如 BOM、空字段表示、不同引号风格)
- 调试困难:复杂正则难以维护,错误提示不直观
真正需要正则的场合,通常是清洗脏数据、提取头部注释、或补救缺失引号的半结构化文本——而不是替代标准 CSV 解析器。










