当在外壳之前找到转义字符时,str_getcsv 不会正确分析数据


str_getcsv does not parse data properly when escape character is found exactly before enclosure

我需要将csv字符串解析为数组。我正在使用 php str_getcsv(),它工作正常,直到我发现下面的情况。

$line = 'field1,field2,field3,"this is field having backslash at end'",anothersomeval';
$arrField = str_getcsv($line, ",", '"');
echo count($arrField);

所以我预计计数应该是 5,但它实际上显示 4。我用谷歌搜索了这个问题,但找不到任何合适的解决方案。我怀疑这是 str_getcsv() 的问题,尽管我找不到任何关于此的错误报告。

我需要使用适当的 csv 解析机制,我不能根据字段分隔符拆分值或只是分解字符串。

关于上述代码出错的地方有什么帮助吗?

str_getcsv()的第

四个参数设置转义字符;默认转义字符为反斜杠。在您的情况下,您正在逃避多宝报价。

如果反斜杠在 csv 字符串中没有特殊含义,并且您希望将其视为文字字符,请使用不同的转义字符调用 str_getcsv(),您可以确保 csv 字符串中不会出现,例如 '#' ,例如:

$arrField = str_getcsv($line, ",", '"', '#');
echo count($arrField);
5

我遇到了同样的问题。我用这个创可贴修复解决了它,它似乎工作得很好,直到有一个选项添加到不使用分隔符的功能中。

//messy CSV content
$csvIn = "'"test 1'", '"test 2'", '"test 3'''", '"test 4'"";
//we will use the ASCII device control 1 character, this should not be in your CSV input
//to make sure it is not, replace all occurrences with an empty string
$csvIn = str_replace("'x11", "", $csvIn);
//convert the csv to array using str_getcsv function and our non-existent delimiter
//make sure the delimiter character is surrounded by double quotes, single quotes will not work
$csvArray = str_getcsv($csvIn, ',', '"', "'x11");
//output the clean results
print_r($csvArray);

我不得不说的第一件事是@user2395126解决方案很好。在评论中,我建议使用不同的方法来定义$csvIn,使用引号而不是双引号作为字符串分隔符,以免转义每个斜杠:

//CSV content with a backslash as last character
$csvIn = '"test 1", "test 2", "test 3'", "test 4"';

解决方案的其余部分应该是 @user2395126 .

然后我尝试了另一种方法:在使用 str_getcsv() 之前转义反斜杠。最后我们得到一个部分结果,包含一个双斜杠而不是单斜杠的数组。需要最后一步。

这是我的完整解决方案:

//CSV content with a backslash as last character
$csvIn = '"test 1", "test 2", "test 3'", "test 4"';
// Escape backslashes
$csvIn = str_replace("''", "''''", $csvIn);
$csvArray = str_getcsv($csvIn, ',', '"');
//output partial result, with double slashes
print_r($csvArray);
//replace double slashes with single one
foreach($csvArray as $key => $item) {
  $csvArray[$key] = str_replace("''''", "''", $item);
}
//output the clean results
print_r($csvArray);