2013-05-10 109 views
1

嗨進出口試圖使一個函數,它在一個CSV文件,然後將其插入文件whitch作品,但沒有什麼,我需要做的。PHP使preg_split爲逗號而不是在雙引號

在我使用爆炸擺脫文件行的時刻..

explode(",", $linearray); 

這workes但如果有類似

field1,field2,field3,field4,"some text, some other text",field6 

我得到這個數組

array(
[0]=>field1, 
[1]=>field2, 
[2]=>field3, 
[3]=>field4, 
[4]=>"some text, 
[5]=>some other text", 
[6]=>field6 
) 

這不是我想要的結果。我知道preg_split可以爲我做,但我不擅長正則表達式。 我想要的結果是。

field1,field2,field3,field4,"some text, some other text",field6 

array(
[0]=>field1, 
[1]=>field2, 
[2]=>field3, 
[3]=>field4, 
[4]=>some text, some other text, 
[5]=>field6 
) 

請大家幫忙。從PHP類

功能CSV文件我已經寫

$lineseparator = "\n"; 
    $fieldseparator = "\n"; 

function ReadFile(){ 
    $this->csvcontent = fread($this->_file,$this->size); 
    fclose($this->_file); 
    return ($this->csvcontent)? true : false ; 
} 
function InsertFileToSQL(){ 
    $query = ""; 
    $i_count = 0; 
    $queries = ""; 
    $linearray = array(); 
    $file_array = explode($this->lineseparator,$this->csvcontent); 
    $lines = count($file_array); 
    foreach($file_array as $key => $value) { 
     $value = trim($value," \t"); 
     $value = str_replace("\r","",$value); 
     /*********************************************************************************************************** 
     This line escapes the special character. remove it if entries are already escaped in the csv file 
     ************************************************************************************************************/ 
     $value = str_replace("'","\'",$value); 
     $value = str_replace("\"","",$value); 
     /***********************************************************************************************************/ 

     $linearray = explode($this->fieldseparator,$value); 

     foreach($linearray as $key2 => $value2){ 
      // Format all fields that match a date format the Reformat for SQL. 
      $date = explode("/", $value2); 
      if(count($date) == 3){ 
       $linearray[$key2] = $date[2]."-".$date[1]."-".$date[0]; 
      } 
     } 

     $linemysql = implode("','",$linearray); 
     if($linemysql != "" && $linemysql != NULL){ 
      if($this->csvheader){ 
       if($key != 0){ 
        if($this->addauto == 1){ 
         $query = "INSERT INTO `$this->db_table` VALUES (NULL,'$linemysql');"; 
        }else{ 
         $query = "INSERT INTO `$this->db_table` VALUES ('$linemysql');"; 
        } 
       }else{ 
        $lines--; 
       } 
       $insert = mysql_query($query) or die(mysql_error()); 
       if($insert){ 
        $queries .= $query . "\n"; 
        $i_count++; 
       } 

      }else{ 
       if($this->addauto == 1){ 
        $query = "INSERT INTO `$this->db_table` VALUES (NULL,'$linemysql');"; 
       }else{ 
        $query = "INSERT INTO `$this->db_table` VALUES ('$linemysql');"; 
       } 
       $insert = mysql_query($query) or die((mysql_error()." in QUERY: ".$query)); 
       if($insert){ 
        $queries .= $query . "\n"; 
        $i_count++; 
       } 

      } 
     }else{ 
      $this->null_row++; 
      $lines--; 
     } 


    } 
    if($this->save) { 
     $f = fopen($this->output_location.$this->outputfile, 'a+'); 

     if ($f) { 
      @fputs($f, $queries); 
      @fclose($f); 
     }else{ 
      echo("Error writing to the output file.", 'error'); 
     } 

    } 
    $lines--;//fix array count 
    $text = ""; 
    if($i_count - $this->null_row != 0){$i_count = $i_count - $this->null_row ;$text .= "<br>$i_count Records were inserted Successfully.";} 
    echo("Found a Total of $lines Record(s) in this csv file.<br>$this->null_row Record(s) were/are Blank or Null.$text", 'success'); 
} 
+4

str_getcsv()更適合這個 - http://www.php.net/manual/en/function.str-getcsv.php;或者如果您正在從CSV文件中讀取數據,請使用fgetcsv() - http://www.php.net/manual/en/function.fgetcsv.php – 2013-05-10 12:28:24

+1

http://stackoverflow.com/questions/2805427/how提取數據從csv-file-in-php記住找一個已經問過同樣問題的人! – 2013-05-10 12:29:16

+0

我知道有很多問題,但沒有我需要的答案。在CSV文件上的PHP函數可以正常工作,但在服務器上不正確。那爲什麼我要求正則表達式的方式,因爲這是一個解決方法,直到服務器問題得到解決。 – MasterT 2013-05-10 12:37:26

回答

1

,我認爲你的答案是在這裏:

exploding a string using a regular expression

由於@Casimir等伊波利特在頁面說:

你可以做的工作使用preg_match_all

$string="a,b,c,(d,e,f),g,'h, i j.',k"; 

preg_match_all("~'[^']++'|\([^)]++\)|[^,]++~", $string,$result); 
print_r($result[0]); 

說明:

訣竅是之前匹配括號,

~   Pattern delimiter 
' 
[^']  All charaters but not a single quote 
++   one or more time in [possessive][1] mode 
' 
|   or 
\([^)]++\) the same with parenthesis 
|   or 
[^,]  All characters but not a comma 
++ 
~ 

,如果你有一個以上的分隔符喜歡的報價(即用於打開和關閉一樣),你可以寫你的模式是這樣,用捕獲組:

$string="a,b,c,(d,e,f),g,'h, i j.',k,°l,m°,#o,p#,@q,[email protected],s"; 

preg_match_all("~(['#@°]).*?\1|\([^)]++\)|[^,]++~", $string,$result); 
print_r($result[0]); 

解釋:

(['#@°]) one character in the class is captured in group 1 
.*?  any character zero or more time in lazy mode 
\1   group 1 content 

隨着嵌套父分析:

$string="a,b,(c,(d,(e),f),t),g,'h, i j.',k,°l,m°,#o,p#,@q,[email protected],s"; 

preg_match_all("~(['#@°]).*?\1|(\((?>[^()]++|(?-1)?)*\))|[^,]++~", $string,$result); 
print_r($result[0]); 
+0

謝謝你,這正是我需要的工作,一種享受,謝謝你,我的朋友 – MasterT 2013-05-12 20:38:49

+0

什麼是空白的像字段1 ,,,字段4 – MasterT 2013-06-13 19:17:01

0

可以使用使preg_split與PREG_SPLIT_DELIM_CAPTURE選項。

$海峽=字段1,字段2,字段3,字段4, 「一些文字,其他一些文字」 欄位6;

那麼像這樣

$match = preg_split("ypir expression", $str, null, PREG_SPLIT_DELIM_CAPTURE); 
+3

更好的選擇是使用內置的CSV處理函數 – 2013-05-10 12:30:36

+0

@MarkBaker內置的CSV函數無法通過換行符正確處理CSV。 – Gerry 2013-05-10 12:34:44

+1

@Gerry - 那麼這個答案是如何處理換行符的,或者OP在他的問題中提到了什麼? – 2013-05-10 12:36:19

0

我不會回答這個問題被問,因爲他要求的錯誤解決他的問題的問題。但是,我希望這個解決方案會更適合他:

在問題的代碼來看,在OP基本上讀通過PHP CSV文件並將其導入MySQL數據庫。

的MySQL實際上提供了直接做這與它的LOAD DATA INFILE語法的方法,而不必解析文件中的PHP的。它比通過PHP處理它快得多,並且完全避免了OP所具有的全部問題。

在PHP中,你只需要做到以下幾點:

$query = <<<eof 
    LOAD DATA INFILE {$filename} INTO {$table} 
    FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' 
    LINES TERMINATED BY '\r\n' 
    IGNORE 1 LINES 
    field1, field2, field3, field4, field5, field6 
eof; 
mysqli_query($conn, $query); 

您可能需要修改查詢了一下代碼中的一些更復雜的東西(即轉換日期格式,等等),但一旦你掌握了LOAD DATA INFILE的語法,你會發現它的合併相當簡單。

我希望有幫助。

+0

好吧,只是爲了清理一些東西,因爲你現在所有的事情。即時通訊這樣做,以便操作數據在手之前更容易,即時通訊正則表達式的方式,因爲有一些文本格式和文字替換也正在使用。我粘貼的功能只是它的基本版本,所以其他人可以根據需要使用它。如果任何人都可以告訴我正則表達式,那將會很棒。 – MasterT 2013-05-10 13:39:30

相關問題