2016-05-10 25 views
2

私はCSVファイルをMySQLデータベースにインポートしています。 CSVを解析するには、fgetcsv()を使用しています。 CSVは、「エスケープされていないcharacetersと原因とを含んでいるerror array_combine(): Both parameters should have an equal number of elementsfgetcsvでエスケープされていない二重引用符を解析する

CSVデータはこの形式である:私は追加

function csv_to_array($filename='', $delimiter=',', $enclosure='"', $escapestring='"') 
{ 
if(!file_exists($filename) || !is_readable($filename)) 
    return FALSE; 

$header = NULL; 
$data = array(); 
if (($handle = fopen($filename, 'r')) !== FALSE) 
{ 
    while (($row = fgetcsv($handle, 1000, $delimiter, $enclosure, $escapestring)) !== FALSE) 
    { 
     if(!$header) 
      $header = $row; 
     else 
      $data[] = array_combine($header, $row); 
    } 
    fclose($handle); 
} 
return $data; 

}

"GR109  "," ",0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0," ","GRANT  ","M   ","W",0,0.0,0.0,0.0,0.0,0.0,0,0,0,0,0,0.0,0.0," ",0,0,0.0," "," "," ",2.42,0.0,0.0,0.0,0.0," "," "," "," "," "," ",0.0,0.0,0.0,0.0,0.0," "," "," "," ","SELF COL ","16 P PR. "," ","PLAIN  "," ","R/E1ROW "," "," "," "," "," "," "," ","R/E1ROW ","BEADED "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","GRANT  ","GRANT  "," "," "," "," ",0.0," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","VAMP LNG - BLK. CARAVELLE P/S. QTR. LNG./ TNG.LINING - BLK. TORINO. (GREY ""TORINO"" FOR LIZARD.)","GR109 COMPLETE" 

私のコード$escapestring='"'しかし、それは助けになりませんでした。 ""文字がエスケープされていない "" TORINO ""からのエラーですか?もしそうなら、これらのフィールドを扱う方法はありますか?

+0

それがあるかのように見えます""(二重二重引用符)は引用符として解析されます。意味、あなたはそれらを置き換える/除外することができ、あなたは行かなくてはなりません。 –

+0

二重引用符がすでに二重引用符でエスケープされているので、 '$ escapestring'を渡す必要はありません。あなたはあなたが投稿した一行にfgetcsvを実行するだけでこれを見ることができ、正しい配列を得ることができます。ヘッダーを含むエラーにつながる最小のCSVを投稿できますか? –

+0

csvファイルをさらに提供できますか?特にヘッダー。ヘッダーの重複したエントリ(空の文字列、数字)はものを混乱させる可能性があります。 – Deus777

答えて

0

Ok。私はそれを見つけたと思う。間違いなくfgetcsvの2番目のパラメータは、ラインの長さであり、ちょっと台無しになっています。単に0に変更してください(機能はかなり遅くなります)、または倍にしてください。 1000だったときは、各行を2行に分けていました.1つは長さがちょうど1000文字(世界の真ん中でさえカットされました)で、2行目は改行文字まで残りの行です。だから、最初の$行変数は再び、その後、約13 117の長さを持つ配列した117と

13.ただ、これを変更:

while (($row = fgetcsv($handle, 1000, $delimiter, $enclosure, $escapestring)) !== FALSE) 

これに:

while (($row = fgetcsv($handle, 0, $delimiter, $enclosure, $escapestring)) !== FALSE) 
+0

これは完全に機能しました。ありがとうございました。 –

+0

ようこそ。 – Deus777

1

あなたのコードは私にとって完璧に機能します。下の例では、サンプルデータにヘッダーが含まれていないため、ヘッダー処理を削除しました。

<?php 

function csv_to_array($filename='', $delimiter=',', $enclosure='"', $escapestring='"') 
{ 
    if(!file_exists($filename) || !is_readable($filename)) 
     return FALSE; 

    $data = array(); 
    if (($handle = fopen($filename, 'r')) !== FALSE) { 
     while (($row = fgetcsv($handle, 1000, $delimiter, $enclosure, $escapestring)) !== FALSE) { 
      $data[] = $row; 
     } 
     fclose($handle); 
    } 
    return $data; 
} 

$result = csv_to_array('test.csv'); 
foreach ($result as $key=>$element) { 
    echo $key . ' => ' . print_r($element,true) . "\n"; 
} 

ファイルtest.csvがあなたの指定したCSV文字列が含まれている場合、明らか出力は(短縮)である:

0 => Array 
(
    [0] => GR109  
    [1] => 
    [2] => 0.0 
    [3] => 0.0 
    // ..... 
    [127] => 
    [128] => VAMP LNG - BLK. CARAVELLE P/S. QTR. LNG./ TNG.LINING - BLK. TORINO. (GREY "TORINO" FOR LIZARD.) 
    [129] => GR109 COMPLETE 
) 
0
$result = preg_replace('/"((?=[^"]*)(?=(?=[^"]*)))"/', '$1', $subject); 

上記の正規表現は、二重の内側に二重引用符を削除します引用符。 これは、との仕事になります。

  1. "いくつかのテキストは、 "内部" よりテキスト"

  2. "複数のテキスト"

を "内部の引用を" 引用します

Ideone demo

関連する問題