2012-03-16 75 views
0

我正在讀取一個CSV文件,但其中一些值未被轉義,因此PHP讀取的內容不正確。這裏是一條線是壞的例子:使用未轉義的存儲模塊讀取CSV文件

「635」,」‘’AUBREY R.菲利普斯(1920-) - 粉彩描繪 小屋一個陡峭的河谷,可能是北威爾士,簽署並註明日期爲 2000框架,66釐米48釐米另一個鄉村景觀,標題爲 「收穫時間,薩默塞特」簽署和日期'87,框架,69釐米49釐米 (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] => 
) 

這顯然是錯誤的,因爲它現在包含了比其他行的正確還有更多的數組元素。

這裏是我使用的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陣列。

我能做些什麼來解決這個問題?謝謝。

+1

應該張貼你如何你的代碼解析CSV,可能有錯誤,但無法幫助或告訴你,沒有你的代碼。 – Churk 2012-03-16 11:42:08

+0

@Churkm完成:) – 472084 2012-03-16 11:50:01

回答

1

如果您知道,您總能獲得條目0和1,並且該數組中的最後5項是總是正確的,所以它只是由於未轉義的機箱字符而「損壞」的描述性條目,那麼可以使用array_slice(),implode()將前兩個和後五個提取回單個字符串(恢復丟失的引號),然後正確重建該數組。

$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妥善逃避外殼

+0

這看起來似乎有點哈克,但如果它是唯一的方法。有希望我不會得到其他領域的「損壞」數據哈哈!一個小問題,你的名字包含「標題爲收穫時間」薩默塞特「簽署和日期」,當原始標題爲'收穫時間,薩默塞特'簽署和日期' – 472084 2012-03-16 12:05:43

+0

這就是爲什麼我添加「不完美,但可能夠好」 – 2012-03-16 12:06:51

0

這是一個遠射,所以不要把我當真。

我在文中看到一個模式,所有'''你想忽略後面有一個空格。 用'FUU'或其他獨特的東西搜索並替換','。

現在解析csv文件。它可能會得到正確的格式。您只需要更換「FUU」回「」

:)

0

你可能將CSV文件的內容作爲一行數組讀取,然後在逗號分隔每行。由於某些字段還包含逗號,因此失敗。一個可以幫助你的技巧是尋找",",這將表明一個字段分隔符,這在字段內不太可能發生(但不是不可能)。

<?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 2012-03-16 11:53:21

1

如果你能ecape了「的文字是這樣的:\」

和在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);