0

CSV ファイルを読み込んでいますが、一部の値がエスケープされていないため、PHP が間違って読み込んでいます。悪い行の例を次に示します。

" 635"," ","AUBREY R. PHILLIPS (1920- ) - 北ウェールズと思われる急勾配の川の渓谷にあるコテージを描いたパステル画、2000 年に署名および日付入り、66cm x 48cm の額入り。 「ハーベスト タイム、サマセット」署名および日付 '87、フレーム入り、69cm x 49cm. (2) NB - オーブリー フィリップスは、スタウアブリッジ スクール オブ アートで学んだウスターシャーのアーティストです。","40","60","WAT ","絵画、版画、水彩画",

Harvest Time、Somersetが引用符で囲まれていることがわかります。これにより、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] => 
)

他の正しい行よりも多くの配列要素が含まれるようになったため、これは明らかに間違っています。

私が使用しているPHPは次のとおりです。

$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配列に入れられます。

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

4

5 に答える 5

1

常にエントリ 0 と 1 を取得し、配列の最後の 5 つのエントリが常に正しいことがわかっている場合、エスケープされていない囲み文字のために「破損」しているのは説明的なエントリだけであり、最初の 2 つを抽出できます。そして最後の 5 をarray_slice()を使用してimplode()で残りを 1 つの文字列に戻し (失われた引用符を復元)、配列を正しく再構築します。

$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)

完璧ではありませんが、おそらく十分です

別の方法は、csv を生成しているユーザーにエンクロージャーを適切にエスケープさせることです。

于 2012-03-16T11:50:55.560 に答える
1

次のようにテキスト内の " をエスケープできる場合: \"

fgetcsv では、エスケープ文字を指定します。

fgetcsv($file, 0, ',', '"','\');
于 2012-03-16T12:22:52.067 に答える
0

CSVファイルの内容を行の配列として読み取ってから、各行をコンマで分割している可能性があります。一部のフィールドにもコンマが含まれているため、これは失敗します。あなたを助けることができる1つのトリックは、を探すことです","。これは、フィールド内で発生する可能性が低い(ただし、残念ながら不可能ではない)フィールドセパレータを示します。

<?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>";
?>
于 2012-03-16T11:51:28.220 に答える
0

これはロングショットなので、真剣に考えないでください。

無視したいすべての「,」の後にスペースがあるテキストのパターンを見ました。「、」を検索して、「FUU」または一意のものに置き換えます。

次に、csv ファイルを解析します。正しいフォーマットになる可能性があります。「FUU」を「,」に戻すだけです。

:)

于 2012-03-16T11:48:35.780 に答える
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);
于 2014-12-11T20:03:08.393 に答える