2009-12-14 125 views
0

在一個項目中,我有一個類似圖案的文字:遞歸正則表達式處理嵌套字符串{|和|

{|文字{| |
更多文字

我想用方括號得到第一部分。爲此我遞歸地使用preg_match。下面的代碼工作已經罰款:

preg_match('/\{((?>[^\{\}]+)|(?R))*\}/x',$text,$matches); 

但是如果我添加符號「|」,我得到了一個空的結果,我不知道爲什麼:

preg_match('/\{\|((?>[^\{\}]+)|(?R))*\|\}/x',$text,$matches); 

我不能使用第一個解決方案,因爲在文本中{text}也可以存在。有人能告訴我我在這裏做錯了什麼嗎? THX

+0

您可以在.NET中使用平衡組,如下所述: http://www.marcomilani.it/2012/07/english-nested-strings-with-regular-expressions-similar-to-recursive-regex。 html?lang = en – Marco 2012-07-17 11:46:34

回答

3

試試這個:

'/(?s)\{\|(?:(?:(?!\{\||\|\}).)++|(?R))*\|\}/' 

在你原來的正則表達式使用字符類[^{}]只是一個分隔符來匹配任何。當分隔符只有一個字符時,這很好,但你的是兩個字符。爲了不匹配多字符序列,你需要的東西,這一點:

(?:(?!\{\||\|\}).)++ 

的點匹配任何字符(包括換行,謝謝給(?s)),但先行已確定只有經過它不是一個{|的一部分或|}序列。我還放棄了原子團體((?>...)),並用佔有量詞(++)取而代之,以減少混亂。但是你肯定應該使用正則表達式的那一部分來防止catastrophic backtracking

+0

我剛剛嘗試過您的解決方案,它運行良好。非常感謝你!也感謝您的解釋,因爲它不容易理解。 – Prog 2009-12-14 08:51:50

1

對於正則表達式的工作你有一些建議,但如果你想知道爲什麼你的原始正則表達式失敗,請繼續閱讀。問題出現在匹配關閉「|}」標籤的時候。 (?>[^{}]+)(或[^{}]++)子表達式將與「|」匹配,導致|}子表達式失敗。如果在子表達式中沒有回溯,則無法從失敗的匹配中恢復。