从CSV数据字符串中删除换行符(PHP 5.3之前)

4

我有一个包含CSV文件内容的大字符串。到目前为止,我并不关心解析它,因为我的程序只是将其从一个源流传输到另一个源。

你的任务,如果你决定接受它,就是告诉我在不丢弃分隔行的换行符的情况下,从包含多个CSV数据行的字符串的数据元素中删除换行符的最佳方法。数据已经被正确引用,并且实现必须在PHP 5.2上运行...

id,data,other
1,"This is data
with a line break I want replacing",1
2,"This is a line with no line break in the data",0
3,No quotes,42
4,"Quoted field with ""quotes inside"" which is tricky",84

每一行都包含固定数量的字段吗?我的意思是,您需要一些信息来指示单个行。例如,每5个逗号我们有一行。 - Melsi
数据来自Web服务器,而不是文件,因此fgetcsv不适用。 - vogomatix
2
可能是 https://dev59.com/8G035IYBdhLWcg3wW-pa 的重复问题。 - faintsignal
不是重复问题,但链接的问题确实提供了有趣的线索 - 谢谢。 - vogomatix
是的,你说得对,链接中的问题的 OP 使用了较新版本的 PHP,我的错。我会在工作时检查一下我们使用的库是否也能正确处理这种情况。 - faintsignal
显示剩余6条评论
1个回答

1
我认为,如果CSV数据中有换行符,则该行上必须有奇数(不成对)引号。如果有这样的一行,请删除它的换行符并检查新创建的行是否有效。
以下伪PHP代码应该可以工作。像ReadercontainsOddNumberOfQuotes()这样的东西很容易在PHP 5.2中实现:
function fixCsv($fileOrString) {
    $reader = new Reader($fileOrString);
    $correctCsv = "";
    while ($reader->hasMoreLines()) {
        $correctCsv = $correctCsv . fixLine($reader, $reader->readLine()) . "\n";
    }
    return $correctCsv;
}

/** Recursive function that returns a valid CSV line. */
function fixLine($reader, $line) {
    if (containsOddNumberOfQuotes($line)) {
        if ($reader->hasMoreLines()) {
            // Try to make a valid CSV line by joining this line with the next one.
            return fixLine($reader, line . $reader->readLine())
        }
        throw new Exception("Last line is incomplete.");
    }
    else {
        return $line;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接