2013-02-19 56 views
2

注意:我首先說我知道我可能錯過了一些非常明顯的東西。我在其中的一種編碼朦朧中無法看到簡單的解決方案。在PHP中確定.csv分隔符

Issue:我已經在PHP中編寫腳本來解析.csv文件,選擇包含電子郵件地址的列,並將它們放入數據庫中。現在,我發現用戶正嘗試上傳具有.csv文件類型的文件,但實際上並未用逗號分隔。我正在嘗試編寫一個能夠正確確定分隔符(製表符,換行符,空格等)的函數,但遇到了一些問題。我想我想獲得所有這些地址的數組,以便按鍵的數量可以將分號添加到該分隔符。

代碼:

$filename = "../some/path/test.csv"; 
if (($handle = fopen($fileName, "r")) !== FALSE) { 
    $delimiters = array(',', ' ', "\t", "\n"); 
    $delimNum = 0; 
    foreach ($delimiters as $delimiter) { 
     $row = 0; 
     while (($data = fgetcsv($handle, 1000, $delimiter)) !== FALSE) { 
     $data = (string)$data[0]; 
     $delimiterList[$delimNum] = explode($delimiter, $data); 
     $row++; 
    } 
    $delimNum++; 
} 
die(print_r($delimiterList)); 
} 

結果:

Array 
(
[0] => Array 
    (
     [0] => email 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
    ) 
) 

就像我說的,我知道這可能是解決這個錯誤的方式,所以我很感激任何你可以提供的見解!

+1

你總是可以添加其他輸入允許用戶指定分隔符。 – Supericy 2013-02-19 00:56:54

+0

我認爲@Supericy的想法是最好的,這似乎並不像你可以輕易確定的東西,除非你有某種基礎從頭開始。 – 2013-02-19 00:58:24

+0

Duplicate:http://stackoverflow.com/questions/3395267/how-to-find-out-if-csv-file-fields-are-tab-delimited-or-comma-delimited – 2015-12-04 14:53:19

回答

1

用可用性而不是代碼解決這個問題。讓用戶選擇分隔符。

但是,由於他們可能不知道標籤分隔的是什麼,CSV等等,只是向他們展示預覽。他們可以從選項中選擇,直到輸出看起來正確和表格。

然後你根據選擇的格式解析它。

1

這不是一個完美的解決方案,但它可能會幫助你 - 如果你不能問分隔符是什麼。

而不是試圖解析爲CSV,嘗試只檢索有效的電子郵件地址。我不認爲空格,逗號,標籤或換行符是否是有效的電子郵件部分? (誰知道;)查看關於using regular expressions to validate email的討論 - 所以你可以看到這個解決方案的一些缺陷。

但是,我會使用preg_match_all()編寫正則表達式,並以有效的電子郵件格式檢索所有字符串的列表。

祝你好運!

0

這是我的解決方案。 它的作品,如果你知道你期望多少列。 最後,分隔符是在手動

actual_separation_character

$separator_1=","; 
$separator_2=";"; 
$separator_3="\t"; 
$separator_4=":"; 
$separator_5="|"; 

$separator_1_number=0; 
$separator_2_number=0; 
$separator_3_number=0; 
$separator_4_number=0; 
$separator_5_number=0; 

/* YOU NEED TO CHANGE THIS VARIABLE */ 
// Expected number of separation character (3 colums ==> 2 sepearation caharacter/row) 
$expected_separation_character_number=2; 


$file = fopen("upload/filename.csv","r"); 
while(! feof($file)) //read file rows 
{ 
    $row= fgets($file); 

    $row_1_replace=str_replace($separator_1,"",$row); 
    $row_1_length=strlen($row)-strlen($row_1_replace); 

    if(($row_1_length==$expected_separation_character_number)or($expected_separation_character_number==0)){ 
    $separator_1_number=$separator_1_number+$row_1_length; 
    } 

    $row_2_replace=str_replace($separator_2,"",$row); 
    $row_2_length=strlen($row)-strlen($row_2_replace); 

    if(($row_2_length==$expected_separation_character_number)or($expected_separation_character_number==0)){ 
    $separator_2_number=$separator_2_number+$row_2_length; 
    } 

    $row_3_replace=str_replace($separator_3,"",$row); 
    $row_3_length=strlen($row)-strlen($row_3_replace); 

    if(($row_3_length==$expected_separation_character_number)or($expected_separation_character_number==0)){ 
    $separator_3_number=$separator_3_number+$row_3_length; 
    } 

    $row_4_replace=str_replace($separator_4,"",$row); 
    $row_4_length=strlen($row)-strlen($row_4_replace); 

    if(($row_4_length==$expected_separation_character_number)or($expected_separation_character_number==0)){ 
    $separator_4_number=$separator_4_number+$row_4_length; 
    } 

    $row_5_replace=str_replace($separator_5,"",$row); 
    $row_5_length=strlen($row)-strlen($row_5_replace); 

    if(($row_5_length==$expected_separation_character_number)or($expected_separation_character_number==0)){ 
    $separator_5_number=$separator_5_number+$row_5_length; 
    } 

} // while(! feof($file)) END 
fclose($file); 

/* THE FILE ACTUAL SEPARATOR (delimiter) CHARACTER */ 
/* $actual_separation_character */ 

if ($separator_1_number==max($separator_1_number,$separator_2_number,$separator_3_number,$separator_4_number,$separator_5_number)){$actual_separation_character=$separator_1;} 
else if ($separator_2_number==max($separator_1_number,$separator_2_number,$separator_3_number,$separator_4_number,$separator_5_number)){$actual_separation_character=$separator_2;} 
else if ($separator_3_number==max($separator_1_number,$separator_2_number,$separator_3_number,$separator_4_number,$separator_5_number)){$actual_separation_character=$separator_3;} 
else if ($separator_4_number==max($separator_1_number,$separator_2_number,$separator_3_number,$separator_4_number,$separator_5_number)){$actual_separation_character=$separator_4;} 
else if ($separator_5_number==max($separator_1_number,$separator_2_number,$separator_3_number,$separator_4_number,$separator_5_number)){$actual_separation_character=$separator_5;} 
else {$actual_separation_character=";";} 

/* 
if the number of columns more than what you expect, do something ... 
*/ 

if ($expected_separation_character_number>0){ 
if ($separator_1_number==0 and $separator_2_number==0 and $separator_3_number==0 and $separator_4_number==0 and $separator_5_number==0){/* do something ! more columns than expected ! */} 
} 
1

SplFileObject::getCsvControl在$我沒有發現它,直到爲時已晚,所以寫了效果很好的功能。 在情況下,它是有用/感興趣我的做法是:

我用$handle$ColName參數與$ColName可選

$ COLNAME讓你檢查它的分隔符的第一個記錄找到一個預期的標題列名,如果csv文件有一個標題行。

如果沒有標題行,或者您不知道列名稱,它將使用默認檢查:哪個分隔符可找到同一記錄的大多數字段(通常這是正確的)。然後,我還檢查該分隔符是否會爲接下來的幾行返回相同數量的字段。

fgetcsv出現在塊工作,並迫使每條記錄有相同數量的該塊中的最大領域,因此這將有不同的每個記錄的字段數甚至工作