2014-03-05 29 views
1

所以我得到了這一點:PHP正則表達式GET支架衝突

$output = "bla bla {_here I am (lots of things) can happen here! it's ok} bla bla"; 
@preg_match_all('/.*{_([^}]*)}/',$output, $conditions); 

結果如預期,直到我們有多個支架。 我想要得到的字符串的內容:

$output = "bla bla {_here I am (lots of things) {conflict} can happen here! it's ok} bla bla"  
@preg_match_all('/.*{_([^}]*)}/',$output, $conditions); 

我想獲得對應於一個括號內容的另一個 結果應該是這樣的:

1. {_here I am (lots of things) {conflict} can happen here! it's ok} 
2. {conflict} 

回答

3

在一般情況下,正則表達式對解析遞歸模式不是一個特別好的選擇,我建議不要使用它們。

如果您知道您輸入只能有支架的兩個層次,這樣的模式就足夠了:

/{_[^{}]*(?:({[^{}]*})[^{}]*)*}/ 

例如:

$output = "bla bla {_here I am (lots of things) {conflict} can happen here! it's ok} bla bla"; 
preg_match('/{_[^{}]*(?:({[^{}]*})[^{}]*)*}/',$output, $conditions); 

然而,PHP確實有支持recursive patterns的擴展。例如:

$output = "bla bla {_here I am (lots of things) {conflict} can happen here! it's ok} bla bla"; 
preg_match('/{(?:[^{}]*|((?R)))*}/',$output, $conditions); 

上述兩個樣本會產生:

Array 
(
    [0] => {_here I am (lots of things) {conflict} can happen here! it's ok} 
    [1] => {conflict} 
) 
1

如果你有超過1個嵌套,您可以使用此模式:

preg_match('~(?=({(?>[^{}]++|(?1))*}))/',$output, $conditions); 

這種模式,使用遞歸((?1)是捕獲組1的別名),會給你所有重疊的結果,因爲它被嵌入到一個先行的斷言中。