2012-03-16 11 views
0

私はCSVファイルを読んでいますが、値の一部がエスケープされていないため、PHPが間違って読み込んでいます。ここで悪いラインの例です。エスケープされていないエンクロージャを使用してCSVファイルを読む

「635」、」 『』 AUBREY R. PHILLIPS(1920-) - でパステル描いたコテージは、急な両面川の渓谷、おそらく北ウェールズ、署名しますそして、 2000年、額入り、66cm×48cmの別の田舎の風景、別名verch "収穫時間、サマセット" 87年署名、日付、69cm×49cm (2)NB - オーブリー・フィリップスはウスターシャーのアーティスト誰が、アートのStourbridgeの学校。 "" 40" 、 "60"、 "WAT"、 "絵画、版画や水彩画 " で学ん

収穫時間、サマセットには引用符が付いているため、PHPは新しい価値を考えると思われます。

私はそれぞれの行にしますprint_r()を行うと、破線はこのように見える終わる:

Array 
(
    [0] => 635 
    [1] => 
    [2] => AUBREY R. PHILLIPS (1920-) - Pastel depicting cottages in a steep sided river valley, possibly North Wales, signed and dated 2000, framed, 66cm by 48cm. another of a rural landscape, titled verso Harvest Time 
    [3] => Somerset" signed and dated '87 
    [4] => framed 
    [5] => 69cm by 49cm. (2) NB - Aubrey Phillips is a Worcestershire artist who studied at the Stourbridge School of Art." 
    [6] => 40 
    [7] => 60 
    [8] => WAT 
    [9] => Paintings, prints and watercolours 
    [10] => 
) 

それは今、他の正しい行よりも多くの配列の要素が含まれているとして、明らかに間違っています。値の間違った量と

$i = 1; 
if (($file = fopen($this->request->data['file']['tmp_name'], "r")) !== FALSE) { 
    while (($row = fgetcsv($file, 0, ',', '"')) !== FALSE) { 
     if ($i == 1){ 
      $header = $row; 
     }else{ 
      if (count($header) == count($row)){ 
       $lots[] = array_combine($header, $row); 
      }else{ 
       $error_rows[] = $row; 
      } 

     } 
     $i++; 
    } 
    fclose($file); 
} 

行が$error_rowsに入れて取得し、残りは大きな$lots配列に入れます:ここで

は、私が使用していますPHPです。

これを回避するにはどうすればよいですか?ありがとう。

+1

は、あなたどのようにあなたのコードを投稿するべきCSVを解析します。間違いかもしれませんが、コードなしで助けたり教えたりすることはできません。 – Churk

+0

@Churkm完了: – 472084

答えて

1

あなたは常にエントリ0と1を取得し、配列の最後の5つの項目が常に正しいことだろうことがわかっている場合は、エスケープされていないエンクロージャー文字のために壊れている記述的なエントリの場合は、array_slice()implode()を使用して残りの部分を1つの文字列に戻して(紛失した引用符を復元する)最初の2個と最後の5個を抽出し、

$testData = '" 635"," ","AUBREY R. PHILLIPS (1920-) - Pastel depicting cottages in a steep sided river valley, possibly North Wales, signed and dated 2000, framed, 66cm by 48cm. another of a rural landscape, titled verso "Harvest Time, Somerset" signed and dated \'87, framed, 69cm by 49cm. (2) NB - Aubrey Phillips is a Worcestershire artist who studied at the Stourbridge School of Art.","40","60","WAT","Paintings, prints and watercolours",'; 

$result = str_getcsv($testData, ',', '"'); 

$hdr = array_slice($result,0,2); 
$bdy = array_slice($result,2,-5); 
$bdy = trim(implode('"',$bdy),'"'); 
$ftr = array_slice($result,-5); 

$fixedResult = array_merge($hdr,array($bdy),$ftr); 
var_dump($fixedResult); 

結果は次のとおりです。

array 
    0 => string ' 635' (length=4) 
    1 => string ' ' (length=1) 
    2 => string 'AUBREY R. PHILLIPS (1920-) - Pastel depicting cottages in a steep sided river valley, possibly North Wales, signed and dated 2000, framed, 66cm by 48cm. another of a rural landscape, titled verso Harvest Time" Somerset" signed and dated '87" framed" 69cm by 49cm. (2) NB - Aubrey Phillips is a Worcestershire artist who studied at the Stourbridge School of Art.' (length=362) 
    3 => string '40' (length=2) 
    4 => string '60' (length=2) 
    5 => string 'WAT' (length=3) 
    6 => string 'Paintings, prints and watercolours' (length=34) 
    7 => string '' (length=0) 

完璧な、しかし十分に可能性が良くない

代替が正しくおそらくある彼らのエンクロージャ

+0

これはちょっとハッキーなようですが、その唯一の方法です。私は他の分野の "腐敗した"データを得ることはできません笑! 1つの小さな問題は、あなたの '収穫のタイトル 'が含まれています。サマーセットは、署名されたと日付'は、 'versoのタイトルがある場合サマーセットは、署名と日付' – 472084

+0

その理由は、 "完璧ではないが、おそらく十分" –

0

これはロングショットなので、真剣に私を服用しないでください。

私はテキスト内に、無視したいすべての '、'にスペースがあることを見ました。 '、'を「FUU」または一意のもので検索して置き換えます。

ここで、csvファイルを解析します。それは正しいフォーマットを得るかもしれません。あなただけ

「」から「FUU」背中を交換する必要があります:)

0

を逃れるために、CSVを生成している誰でも取得することですCSVファイルの内容を行の配列として読み取った後、各行をコンマで区切ります。いくつかのフィールドにもカンマが含まれているため、これは失敗します。あなたを助けてくれる1つのトリックは、","を探すことです。これは、フィールド内で発生する可能性は低い(残念ながら不可能ではない)フィールド区切りを示します。あなたはecape「このようなテキストで:\」することができた場合は

<?php 
    $csv = file_get_contents("yourfile.csv"); 
    $lines = split("\r\n", $csv); 
    echo "<pre>"; 
    foreach($lines as $line) 
    { 
    $line = str_replace("\",\"", "\"@@@\"", $line); 
    $fields = split("@@@", $line); 
    print_r($fields); 
    } 
    echo "</pre>"; 
?> 
+0

私は今使っているPHPで私のQを編集しました – 472084

1

とfgetcsvで使用するエスケープ文字目の指定​​

fgetcsv($file, 0, ',', '"','\'); 
0
$csv = explode(' ', $csv); 
foreach ($csv as $k => $v) if($v[0] == '"' && substr($v, -1) == '"') { 
    $csv[$k] = mb_convert_encoding('&ldquo;' . substr($v, 1, -1) . '&rdquo;', 'UTF-8', 'HTML-ENTITIES'); 
} 
$csv = implode(' ', $csv); 
$csv = str_getcsv($csv); 
関連する問題