CSV数据内换行符导致Text::CSV读取异常,如何解决?
解决Text::CSV读取Google Sheets导出数据时的内嵌换行问题
嘿,这个问题我之前帮人排查过好几次,Text::CSV碰到内嵌换行符确实容易翻车,尤其是从Google Sheets导出的数据——毕竟Sheets里的单元格换行本来就是用\n存的,但CSV规范里内嵌换行得用引号包起来才行。给你几个靠谱的解决思路:
让Google Sheets导出时自动处理内嵌换行
直接从Sheets导出CSV时,默认应该会把带换行的单元格用双引号包裹,但有时候会因为数据格式(比如单元格是公式计算结果)或者导出设置导致失效。你可以先把描述列的格式改成「纯文本」,再重新导出CSV。导出后打开文件检查下,带\n的单元格是不是被"括起来了,这是最省心的办法。配置Text::CSV的参数兼容内嵌换行
Text::CSV本身就支持处理内嵌换行,你只需要在初始化对象时开启关键参数:use Text::CSV; my $csv = Text::CSV->new({ binary => 1, # 支持非ASCII字符和内嵌换行、回车 auto_diag => 1, # 自动输出错误诊断信息,方便排查问题 quote_char => '"', # 指定双引号作为字段包裹符 allow_whitespace => 1, # 如果字段前后有空格也能正确识别(可选) });开启
binary是核心,它会让Text::CSV按照CSV规范正确解析被引号包裹的内嵌换行,不会把\n当成行结束符。预处理数据替换换行符(应急方案)
如果上面两种办法都不适用,可以先把Sheets里的换行符替换成占位符,读取后再还原:- 在Sheets里用公式替换:
=SUBSTITUTE(你的描述单元格, CHAR(10), "[[NEWLINE]]")(Sheets里的换行对应CHAR(10),也就是\n) - 脚本读取CSV后再反向替换:
$description_field =~ s/\[\[NEWLINE]]/\n/g;
这个办法比较直接,适合一些特殊格式的场景。
- 在Sheets里用公式替换:
小提醒:如果你的脚本是直接调用Google Sheets API拉数据,那拿到的原始数据里换行符就是\n,这时候只要用上面配置好的Text::CSV对象写入CSV,它会自动给带换行的字段加上引号,不用额外处理。
内容的提问来源于stack exchange,提问作者Andrew Newby
相关产品推荐
相关产品推荐

