2009-01-22 65 views
6

解析CSV表達我已經設法使用這種正則表達式來拆分CSV文件: 「/,(=(?:?[^ \」] \ 「[^ \」] \「)(?![^ \「] \」))/「經常在PHP

但是,我結束了包含開始和結束雙引號的字符串數組。 現在我需要一個正則表達式來去除分隔符的雙引號字符串。

據我所知,CSV格式可以用雙引號封裝字符串,並且已經是字符串一部分的所有雙引號都加倍。例如:

我的「其他」貓

成爲

「我的‘’其他」,「貓」

我基本上需要的是一個正則表達式,將代替n雙引號的所有序列與(N/2 - 舍入)雙引號的序列。

或者還有更好的方法嗎? 在此先感謝。

回答

21

有閱讀的CSV文件功能:fgetcsv

+10

+1你瘋了使用正則表達式對於PHP中的CSV,當內置函數完全按照你想要的方式執行時 – cletus 2009-01-22 22:03:53

+1

是的,爲什麼你需要重新發明輪子,當有什麼東西在那裏經過很好的測試,哪些工作可以解決你的問題。 – Rachel 2010-03-17 14:19:02

+1

因爲也許你從第三方獲得的CSV導出沒有正確引用文本字段,並且fgetcsv錯誤地將字符串1.15解釋爲值爲1.1499999999的浮點數。但是,最後編寫一個快速腳本來修復CSV文件然後使用fgetcsv會更容易:o) – frak 2014-12-11 18:47:16

0

這是我的快速嘗試,雖然它只會在字邊界上工作。

preg_replace('/([\W]){2}\b/', '\1', $csv) 
4

爲什麼你懶得分裂與正則表達式的文件時,有fgetcsv函數,它把所有的辛勤工作的嗎?

您可以傳入分隔符和分隔符,它會檢測要執行的操作。

2

我同意其他人說你應該使用fgetcsv函數而不是正則表達式。正則表達式可以在格式良好的CSV數據上正常工作,但是如果CSV格式不正確或損壞,則正則表達式將默默失敗,可能會在過程中返回虛假結果。

但是,這個問題具體是關於在初始分割後剝離不需要的引號。提出的解決方案(迄今爲止)太天真了,它只能處理字段中的轉義引號,而不是實際的分隔符。 (我知道OP並沒有問這些,但他們確實需要被移除,因此在同爲別人爲什麼不這樣做呢?)這是我的解決方案:

$csv_field = preg_replace('/"(.|$)/', '\1', $csv_field); 

此正則表達式引號匹配隨後是任何字符或字符串的末尾,並用第二個字符替換匹配的字符,如果匹配的是$,則替換爲空字符串。根據規範,CSV字段可以包含行分隔符;這似乎並沒有太多的發生,但如果需要的話,你可以在正則表達式中添加's'修飾符。

1

對於那些不想使用正則表達式而不是fgetcsv的人。這裏是一個完整的例子,如何使用正則表達式從csv創建一個html表格。

$data = file_get_contents('test.csv'); 
    $pieces = explode("\n", $data); 

    $html .= "<table border='1'>\n"; 
    foreach (array_filter($pieces) as $line) { 

      $html .= "<tr>\n"; 
      $keywords = preg_split('/,(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))/', $line,-1,PREG_SPLIT_DELIM_CAPTURE); 

      foreach ($keywords as $col) { 
        $html .= "<td>".trim($col, '"')."</td>\n"; 
      } 
      $html .= "</tr>\n"; 
    } 
    $html .= "</table>\n"; 
2
preg_split('/,(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))/', $line,-1,PREG_SPLIT_DELIM_CAPTURE); 

具有與玩具 「反 」鬥「 之類的字符串裏的」」

,這樣你們應該使用問題:

preg_split('/'.$seperator.'(?=(?:[^\"])*(?![^\"]))/', $line,-1, PREG_SPLIT_DELIM_CAPTURE);