2012-11-27 36 views
-1

我想從我們的數據庫中獲取一些註釋行,它們存儲爲字符串,由'\ n'分隔。不幸的是,在一些評論中包含文本 - 也用'\ n',並且我沒有相應地將它們分開。RegExp獲得換行符線

一個例子評論是這樣的:

27.11.2012 13:19 (MB): test123 
27.11.2012 13:20 (MB): test456 
27.11.2012 13:21 (JA): test789 
lalala 
lululu 
27.11.2012 13:22 (JA): test10 

現在,我嘗試了將它們分開使用一個reg exp和使preg_split():

#(\d{2}\.\d{2}\.20[0123]{2} \d{2}:\d{2} \([A-Z]{2,3}\): .*)# 
(PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE) 

,但我得到

Array 
(
    [0] => 27.11.2012 13:19 (MB): test123 
    [1] => 
    [2] => 27.11.2012 13:20 (MB): test456 
    [3] => 
    [4] => 27.11.2012 13:21 (JA): test789 
    [5] => 
lalala 
lululu 
    [6] => 27.11.2012 13:22 (JA): test10 
) 

如何我能把他們結合起來嗎?

回答

0

正則表達式中的一個點與換行符不匹配,因此您的.*會轉到該行的末尾;看似空的行包含換行符。因此,從您的分割模式中刪除.*,並使用其餘的PREG_SPLIT_DELIM_CAPTURE

(\d{2}\.\d{2}\.20[0123]{2} \d{2}:\d{2} \([A-Z]{2,3}\):) 

每一行將在結腸被分成兩個部分。然後,您可以成對加入您的字符串以獲得原始行(或者在您需要分隔字段時節省您在程序的下一步中分割它們的麻煩)。

如果你真的很討厭你的拆分輸入行的想法:

  1. 使用preg_match_all而不是分裂。
  2. 添加PCRE_DOTALLs)標誌來修改.的含義,以便它也匹配換行符。
  3. 這會使第一個.*一直匹配到文件的末尾,因此請將其設置爲非貪婪:.*?

現在,你需要匹配所有的東西,直到下一個日期模式,但是在之前停止吧。您可以通過用超前表達式結束正則表達式來表達這一點。由於它將分隔您的匹配組,因此您不再需要將其明確地放入匹配的模式中。

換句話說,嘗試這種模式(我已經添加了s標誌作爲後綴,當然你可以單獨將它傳遞):

/(.*?)\n(?=\d{2}\.\d{2}\.20[0123]{2} \d{2}:\d{2} \([A-Z]{2,3}\):)/s 

評論:我避免向前看符號/ lookbehinds不亞於可能的,你可能會明白爲什麼。我發現這個兩部分的解決方案更簡單,更易維護,但是這裏的前瞻是有意義的。

PS。如果更改文件格式仍然是一種選擇,請考慮轉換爲csv格式並使用fgetcsv或類似內容讀取它。

+0

謝謝你的回答。我試圖避免得到兩條線,但會處理它... – manuxi

+0

如果你真的討厭這個,試試我剛剛添加的第二個變體。 – alexis

+0

我只是處理它,但很好奇,無論你的第二個正則表達式給出更好的結果: 但preg_match_all(self :: $ sRegExpDateTimex,$ sComment,$ aMatches);只給我直到冒號的路線...... – manuxi