Parsing CSV file into array


  • snippets
  • (Updated at )

記得數年前就有寫過匯入 CSV 資料的程式,不過要翻出來可以能重寫還快多了,本想說應該已有不少輪子在網路上,可惜找了一下還是找不到正確或是較有效率的處理方式,而 PEAR::File_CSV 也不明原因不存在,後來找到了一個簡單正確又有效率 Regular Expression 以此又重新寫了一個新 php function.

測試結果也另人滿意,在混搭的情形下也可以正確解析:

  
Test string: "Name","Nick Name","Age","Hair Color"  
Array  
(  
    [0] => Name  
    [1] => Nick Name  
    [2] => Age  
    [3] => Hair Color  
)  
  
Test string: 'Name','Nick Name','Age','Hair Color'  
Array  
(  
    [0] => Name  
    [1] => Nick Name  
    [2] => Age  
    [3] => Hair Color  
)  
  
Test string: "Name";"Nick Name";"Age";"Hair Color"  
Array  
(  
    [0] => Name  
    [1] => Nick Name  
    [2] => Age  
    [3] => Hair Color  
)  
  
Test string: Kim,"Kim ""Hot Legs"" Smith",24,"Brunette"  
Array  
(  
    [0] => Kim  
    [1] => Kim "Hot Legs" Smith  
    [2] => 24  
    [3] => Brunette  
)  
  
Test string: "Sarah Vivenz, II","Stub's",27,"Brunette"  
Array  
(  
    [0] => Sarah Vivenz, II  
    [1] => Stub's  
    [2] => 27  
    [3] => Brunette  
)  

php code:

  
/**  
 * parsing csv file into array  
 *  
 * @return array  
 * @author Ethan Liu  
 **/  
function parser_csv($filepath, $header = '', $limited = 0) {  
  set_time_limit(0);  
  $result = array();  
  $x = 0;  
  $pattern = '/("(?:[^"]|"")*"|[^",\r\n]*)(,|;|\r\n?|\n|\r)?/';  
  $patterns = array(  
    '/^["\']|["\']$/',  
    '/("|\'){2}/'  
  );  
  $replacement = array(  
    "",  
    "$1"  
  );  
  
  if (!is_file($filepath)) {  
    return $result;  
  }  
  
  $f = @fopen($filepath, "r");  
  if (empty($f)) {  
    @fclose($f);  
    return $result;  
  }  
    
  switch ($header) {  
    case 'ignore':  
      $buffer = fgets($f);  
    break;  
  }  
  
  while (!feof($f)) {  
    if ($limited > 0) {  
      $x++;  
      if ($x > $limited) {  
        break;  
      }  
    }  
    $buffer = trim(fgets($f));  
    if (empty($buffer)) {  
      continue;  
    }  
    preg_match_all($pattern, $buffer, $matches);  
    $matches[1] = preg_replace($patterns, $replacement, $matches[1]);  
    if (empty($matches[1][count($matches[1])-1])) {  
      unset($matches[1][count($matches[1])-1]);  
    }  
    $result[] = $matches[1];  
  }  
    
  @fclose($f);  
  unset($buffer);  
  unset($matches);  
  return $result;  
}  
0 comment, 0 pingback