2013-04-23 25 views
0

我在php中使用preg_match_all來構造寫在DSL中的字符串的標記。當我將測試字符串硬編碼到我的PHP代碼中並運行它時,它都可以工作。但是,當我從數據庫中讀取相同的字符串時,它會匹配前兩個標記,然後將其餘的字符串匹配爲一個標記,當清楚地將其拆分爲多個子單元時,就像字符串被硬編碼時一樣。php中的preg_match_all產生與數據庫字符串不同的結果

這怎麼可能?

我正在使用。+在我的正則表達式中匹配「其餘」。基本上我的DSL包括關鍵字和休息,所以我對preg_match_all正則表達式如下:

/(?P<NameOfKeyword1>Keyword1)|(?P<NameOfKeyword2>Keyword2)|(?P<NameOfKeyword3>Keyword3)|(?P<Linebreak>\\v+)|(?P<Rest>.+(?=Keyword1)|.+(?=Keyword2)|.+(?=Keyword3)|.+)/ 

基本上,我的第一場比賽的關鍵詞,然後我匹配換行符,那麼剩下的,直到下一個關鍵字(或斷行或結束的字符串)出現。

那麼爲什麼它在字符串硬編碼時正確匹配,但是當從數據庫中讀取相同的字符串時不能正確匹配?

當從數據庫中讀取匹配爲一個標記的字符串的其餘部分時,不應該將其作爲一個標記進行匹配,因爲它們之間有關鍵字。它看起來像它匹配它基於+

編輯: 我使用的preg_match_all的標誌是PREG_SET_ORDER和PREG_OFFSET_CAPTURE

+0

也許字符編碼問題? – Barmar 2013-04-23 07:37:57

+0

可能,我該如何檢查? – user975561 2013-04-23 08:07:36

+0

從數據庫中讀取字符串,然後將其與硬編碼字符串進行比較。 – Barmar 2013-04-23 08:27:27

回答

1
(?P<Rest>.+(?=Keyword1)|.+(?=Keyword2)|.+(?=Keyword3)|.+) 

這並不意味着「那麼剩下的,直到下一個關鍵字(或換行或字符串結束)出現。「。事實上,除了新線以外,它永遠不會停止。
爲什麼?你正在使用lookaheads。基本上,.(?=Keyword1)的意思是「任何字符後跟Keyword1」(+它只是表示「一系列字符,每個字符都跟着Keyword1」)。
所以那些不會匹配任何東西。最後的.+是其餘完全匹配的原因。

現在,如果你讓他們lazy,這應該有預期的輸出:

(?P<Rest>.+?(?=Keyword1|Keyword2|Keyword3|$)) 

編輯:
還應該檢查\五:

/(?P<NameOfKeyword1>Keyword1) 
|(?P<NameOfKeyword2>Keyword2) 
|(?P<NameOfKeyword3>Keyword3) 
|(?P<Linebreak>\v+) 
|(?P<Rest>.+?(?=Keyword1|Keyword2|Keyword3|\v|$))/ 
+0

當我用你的正則表達式替換它時,它不再與其他表達式匹配。只有關鍵字和很少的「休息」。 – user975561 2013-04-23 08:09:08

+0

你能舉個例子嗎?這將更容易測試。 – Loamhoof 2013-04-23 08:16:41

+0

下面是一個示例字符串:http://pastebin.com/qS5Qaqhh它遺漏了「Test Talk」,但發現了其他所有內容。對於很多其他的字符串,它可以工作。 – user975561 2013-04-23 09:05:24

相關問題