1

PHPでCSVファイルを解析する必要があります。CSV ファイルはクライアントから提供されたもので、形式を制御することはできません。コンマ区切りで、テキスト修飾子として二重引用符を使用します。ただし、アドレス フィールドなどのフィールドにコンマが含まれている場合、クライアントのシステムはそのフィールドを追加の二重引用符で囲みます。例えば:

"9999X111","X1110000110105","John Doe",""123 Central Park Avenue, #108"","New York NY 10006 ","","","M","0","1","370.20"

ご覧のとおり、4 番目のフィールド (3 番目のインデックス) には、フィールド全体を囲む二重引用符の余分なセットがあります。この文字列を fgetcsv() または str_getcsv() で送信すると、フィールドが正しく処理されません。

Unwanted Result Array:
[0] => 9999X111
[1] => X1110000110105
[2] => John Doe
[3] => 555 Central Park Avenue
[4] =>  #108""
[5] => New York NY 10006

余分な二重引用符のセットを手動で削除すると、行はどちらの関数を使用しても正しく処理されます。ただし、実稼働環境ではこれを行うことはできません。

Preferred Result Array:
[0] => 9999X111
[1] => X1110000110105
[2] => John Doe
[3] => 555 Central Park Avenue, #108
[4] => New York NY 10006

私が使用している現在のコードは次のとおりです。

$fileCHG = fopen($fileloc['InputFile'], "r");
$cnt = 0;
while(!feof($fileCHG)) {
    $chg[$cnt] = fgetcsv($fileCHG,0,",","\"");
    if($chg[$cnt]=="") { //Unset Any Blank Arrays
        unset($chg[$cnt]);
    }
    $cnt++;
}

Stack Overflow や PHP のマニュアルなどからさまざまな提案を試してみましたが、うまくいかないようです。二重引用符の内側のセットをバックスラッシュで手動でエスケープしても、正しくない結果配列が得られます。どちらの関数をどのように使用しても、スクリプトは台無しになり、「Avenue」に続くコンマでフィールドを分割しようとし、残りの「」を無視します。

PHP サイトのこのコメントは、何が起こっているのかを説明しているように感じますが、新しいコーダーとして、実際に何が起こっているのかを視覚化することはできません。

http://www.php.net/manual/en/function.fgetcsv.php#58124

また、次の提案を(多くの中から)試してみましたが、役に立ちませんでした。

fgetcsv はデータを適切に分割していません str_getcsv はデータを正しく解析していません

この方法はうまくいった可能性があります。ただし、各行のフィールド数が同じである必要があります。

エスケープされていないエンクロージャーを含む CSV ファイルの読み取り

Mac OS X 10.8 で PHP 5.3.27 を使用しています。

ご覧いただきありがとうございます。

4

1 に答える 1

1

Daniel と Cosades が残したコメントを拡張することで、問題を解決することができました。fgetcsv() を使用して行をすぐに処理する代わりに、fgets() を使用して行を変数 ($line) に格納します。次に、stripos() を使用して、重複する二重引用符 ("") が出現するすべての場所を見つけました。次に、前後の文字がコンマ (,) ではないかどうかを判断して、編集が必要な場所を特定します。以下は私の新しいコードです。

$fileCHG = fopen($fileloc['Charge'], "r");
$cnt = 0;

while(($line=fgets($fileCHG))!==false){
    $pos = 0;
    while($pos=stripos($line,"\"\"",$pos)){
        $chrA = substr($line,$pos-1,1);
        $chrB = substr($line,$pos+2,1);

        if($chrA!=","){
            $line   = substr_replace($line,"",$pos+1,1);
        }

        if($chrB!=","){
            $line   = substr_replace($line,"",$pos+1,1);
        }   

        $pos = $pos + strlen(",\"\"");
    }

    if($line!=""){
        $chg[$cnt] = str_getcsv($line,",","\"");
    }

    if($chg[$cnt]==""){
        unset($chg[$cnt]);
    }    

    $cnt++;
}

私を正しい方向に向けてくれてありがとう!

于 2013-09-09T21:09:30.003 に答える