繁体   English   中英

修复不带引号的多行CSV字符串(使用PHP)

[英]fix multi-line CSV string without quotes (using PHP)

我有一个CSV文件,其中带有逗号的字符串会引起引号,但其中没有逗号的字符串不会得到引号。 问题是:多行字符串(不带逗号)在字符串周围没有引号。 我如何将它们视为一个领域?

例如,第3-5行在多行字符串周围没有引号:

id1,h2,h3,h4
2,2a:with comma and quote / middle field,"3,a
b
c",4a
3,2a:no comma no quote / last field,3a,4a
b
c
4,2a:no comma no quote / middle field,3a
b
c,4a
5,2a:no comma no quote / middle and last field,3a
b
c,4a
b
c

问:最好使用PHP(或awk / sed / Python / Perl /其他* nix CLI工具)创建所需输出的首选/最简洁方法是什么?

  • 选项a(首选):在多行字符串周围加上引号
  • 选项b(解决方法):对于没有引号的多行字符串,请使用分隔符(例如|)代替换行符

选项A:首选-在多行字符串周围加上引号

id1,h2,h3,h4
2,2a:with comma and quote / middle field,"3,a
b
c",4a
3,2a:no comma no quote / last field,3a,"4a
b
c"
4,2a:no comma no quote / middle field,"3a
b
c",4a
5,2a:no comma no quote / middle and last field,"3a
b
c","4a
b
c"

选项B:解决方法-对于没有引号的多行字符串,请使用分隔符(例如|)代替换行符

id1,h2,h3,h4
2,2a:with comma and quote / middle field,"3,a
b
c",4a
3,2a:no comma no quote / last field,3a,4a|b|c
4,2a:no comma no quote / middle field,3a|b|c,4a
5,2a:no comma no quote / middle and last field,3a|b|c,4a|b|c

在我的文本文件中:

  • 每行始终具有4个字段(一行或包含多行字符串时分成多行)
  • 如果字符串中有逗号(在多行字符串中也适用),则在字符串两边加引号
  • 第一列是整数
  • 只有字符串字段应该在它周围加上引号

这是我目前正在使用的代码。 (对我而言)它有效,但是我觉得可以(一种)更有效的方式来完成它。

<?php

$inputFile = "test.csv"; 
$outputFile = "output.csv";

$in = fopen($inputFile, "r") or die("could not open ".$inputFile);
$out = fopen($outputFile, 'w');

$rowCount = 0;

//column count
$firstLine = fgetcsv($in);
$columnCount = count($firstLine);
fputcsv($out, $firstLine);

$buffer = array();

while ($line = fgetcsv($in) ) {

    $rowCount++;

    // new line: put in buffer
    if (!count($buffer)) {
        $buffer = $line; 
        continue;
    }

    // new line is not starting with number, and not complete
    if (count($line) != $columnCount && !is_numeric($line[0]) ) {
        $first = array_shift($line);
        $buffer[count($buffer)-1] .= "\n". $first;
        $buffer = array_merge($buffer,$line);
    }

    // row is complete
    if (count($line) == $columnCount || (count($line)>0 && is_numeric($line[0]) ) && count($buffer) == $columnCount ) {
        fputcsv($out, $buffer);
        $buffer = $line;
    }
}

// write final buffer
if (count($buffer)) {
    fputcsv($out, $buffer);
}

fclose($in);
fclose($out);

?>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM