2013-01-21 48 views
1

我有一個我想使用PHP解析的CSV文件(不想使用php csv函數,因爲它們對於我的例子來說太慢了)。我使用preg_replace來只選擇我需要的列並將輸出寫回標準輸出。我有一個看起來像這樣的模式preg_replace正則表達式 - 跳過與模式不匹配的行的輸出

preg_replace("/^\"([^\"]*)\",\"([^\"]*)\"(.*)$/m", "$1;$2", $content); 

CSV中有一些行格式不正確。有沒有辦法跳過與上面的模式不匹配的行的輸出?

+1

你真的認爲fgetcsv()或str_getcsv比自制正則表達式慢嗎?我很想看到一些基準測試結果 –

+0

是的,fgetcsv和str_getcsv都將數據解析爲非常緩慢的php數組。與下面描述的需要aprox的解決方案相比,使用stream_get_content和str_getcsv的解決方案需要33s來解析290MB的CSV文件。 5秒。 –

+0

有趣的結果,我將不得不運行我自己的一些測試...我有一個CSV應用程序,這種速度的改進將是一個真正的好處大型文件 –

回答

2

你可以做的兩個步驟:

首先刪除不符合您的正則表達式的所有行:

preg_replace("/^(?!\"([^\"]*)\",\"([^\"]*)\".*$).*\r?\n/m", "", $content); 

然後做原來的正則表達式替換。

但是,您需要非常小心地。只要您的CSV字段中有換行符和/或轉義引號,這些正則表達式可能會破壞並破壞您的文件。

或者想像這樣

"foo","bar (missing quote!) 
"baz", "bam" (correct line) 

正則表達式格式不正確的行現在將同時刪除未完成正確的路線,因爲[^\"]*也吃換行符。

+0

感謝您的答案,特別是警告。我目前的想法是假設大多數csv文件格式良好,所以我做了正則表達式替換和比較替換前後的字符串長度。如果他們是一樣的一切都好,否則我一行一行地做。 –