【问题标题】:PHP reading csv, issue with double quotesPHP读取csv,双引号问题
【发布时间】:2014-07-06 00:49:11
【问题描述】:

我有一个 csv 文件,它有 6 行,如下所示:

10264,dan,Dan,37519,MILLER,6/3/2014 14:51,$28.40,Rapid,Dan@Cold.com,,
10443,Dari,"D. R, LLC",37308,SELLERS,6/2/2014 15:12,$40.00,esponse,chards@lobal.net,,
10488,EmHern,"A HOME FOR YOU,LLC",37749,MILLER,6/1/2014 8:23,$33.00, Response,23@YAHOO.COM,,

我尝试读取该 csv 并提取一些列,然后为提取的每一列添加一个管道分隔符,这是我使用的函数:

<?php
function fncReadCSV($csvFileName){
    $result = array();
    $row = 1;
    if (($handle = fopen($csvFileName, "r")) !== FALSE) {
            while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
                $outPut = "";
                $outPut .= $data[0];
                $outPut .="|";
                $outPut .= $data[1];
                $outPut .="|";  
                $outPut .= $data[2];
                $outPut .="|";  
                $outPut .= $data[6];
                $outPut .="|";  
                $outPut .= $data[8];
                $outPut .="|";                                  
                array_push($result, rtrim($outPut, "|"));
                $row++;
            }               
           }
    fclose($handle);
    return $result;
    }
echo "<pre>";
print_r(fncReadCSV("file.csv"));
echo "</pre>";

我得到的结果仅对第一行是正确的,对于第二、第三行,我得到了完整的行,因为它在 csv 中,我希望引号会破坏我的代码我该如何解决这个问题适用于带有引号的 csv 文件和不带引号的 csv 文件的代码?

结果是:

Array
(
    [0] => 10264|dan|Dan|$28.40|Dan@Cold.com
    [1] => 10443,Dari,"D. R, LLC",37308,SELLERS,6/2/2014 15:12,$40.00,esponse,chards@lobal.net,,
    [2] => 10488,EmHern,"A HOME FOR YOU,LLC",37749,MILLER,6/1/2014 8:23,$33.00, Response,23@YAHOO.COM,,
)

我期待的结果是:

Array
    (
        [0] => 10264|dan|Dan|$28.40|Dan@Cold.com
        [1] => 10443|Dari|"D. R, LLC"|esponse|chards@lobal.net
        [2] => 10488|EmHern|"A HOME FOR YOU,LLC"|37749|23@YAHOO.COM
    )

【问题讨论】:

    标签: php csv fgetcsv


    【解决方案1】:

    fgetcsv() 应该处理单引号,事实上 fputcsv() 的默认输出是引用( wrap )任何带有空格的行。完全可以预期在带有分隔符的字符串周围使用“”,“单词,其他单词”,使用 fgetscsv 100% 没问题。

    试试这个

    echo '<pre>';
        if (($handle = fopen($csvFileName, "r")) !== FALSE) {
            while (false !== ($data = fgetcsv($handle, 1024))) {
    print_r($data);
                $data_row = array(
                    $data[0],
                    $data[1],
                    $data[2],
                    $data[6],
                    $data[8]
                );                            
               $result[] = implode("|", $data_row);
               $row++;
            }               
        }
            fclose($handle);
            return $result;
    

    implode 更简洁一些,你不需要修剪额外的“|” ?,因为我认为它没有任何目的,为什么不直接省略最后一个(最右边的)|。

       $outPut .="|";                                  
       array_push($result, rtrim($outPut, "|"));
    
    
       array_push($result, $outPut));
    

    事实上,运行你的确切代码会给我这个输出?

    $result = array();
            $row = 1;
            if (($handle = fopen(__DIR__.'/test.csv', "r")) !== FALSE) {
                while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
                    $outPut = "";
                    $outPut .= $data[0];
                    $outPut .="|";
                    $outPut .= $data[1];
                    $outPut .="|";
                    $outPut .= $data[2];
                    $outPut .="|";
                    $outPut .= $data[6];
                    $outPut .="|";
                    $outPut .= $data[8];
                    $outPut .="|";
                    array_push($result, rtrim($outPut, "|"));
                    $row++;
                }
            }
            fclose($handle);
    
    array(
    '0' => '10264|dan|Dan|$28.40|Dan@Cold.com',
    '1' => '10443|Dari|D. R, LLC|$40.00|chards@lobal.net',
    '2' => '10488|EmHern|A HOME FOR YOU,LLC|$33.00|23@YAHOO.COM'
    )
    

    运行我的代码给了我

    array(
    '0' => '10264|dan|Dan|$28.40|Dan@Cold.com',
    '1' => '10443|Dari|D. R, LLC|$40.00|chards@lobal.net',
    '2' => '10488|EmHern|A HOME FOR YOU,LLC|$33.00|23@YAHOO.COM'
    )
    

    这里是你的解决方案

    echo "<pre>";
    $result = array();
            $row = 1;
            if (($handle = fopen(__DIR__.'/test.csv', "r")) !== FALSE) {
                while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
                    if(count($data) == 1){
                        $f = fopen('php://temp', 'w');
                        fwrite($f, $data[0]);
                        rewind($f);
                        $data = fgetcsv($f, 1000, ",");
                        fclose($f);
                    }
    
                    $data_row = array(
                        $data[0],
                        $data[1],
                        $data[2],
                        $data[6],
                        $data[8]
                     );                            
                    $result[] = implode("|", $data_row);
                    $row++;
                }
            }
            var_export($result);
            fclose($handle);
    

    输出

    array(
    '0' => '10264|dan|Dan|$28.40|Dan@Cold.com',
    '1' => '10443|Dari|D. R, LLC|$40.00|chards@lobal.net',
    '2' => '10488|EmHern|A HOME FOR YOU,LLC|$33.00|23@YAHOO.COM'
    )
    

    解释

    getcsv 由于外部引号“而返回单个元素,但它会去除围绕“D. R, LLC" 位(witch 给了我们一个类似于第 1 行的字符串),然后检查该单个元素,并将其写入临时缓冲区,(流包装器)并使用 fgetcsv 重新处理流,瞧!

    【讨论】:

    • 对不起,我不明白,请问可以解决这个问题吗?
    • 您的 csv 在不计算列的情况下看起来很好,也就是说,“D.R, LLC”很好。
    • 对不起,我在 print_r 中有两个 rr,print_r 将在每一行上打印数据,这样您就可以验证 csv 是否被正确读取,pre 标记保留空白并更容易读取 print_r 输出。
    • 抱歉您的代码没有修复它,我知道我的 csv 很好,但我想知道如何在 PHP 中处理它
    • 用什么?具体来说,我一直使用带引号的 fgetcsv,即使使用悬挂的 " 单双引号,您的输出也毫无意义,您将无法获得该输出。
    猜你喜欢
    • 2022-01-15
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多