2013-02-05 197 views
3

在PHP中,我有以下字符串:PHP:正則表達式匹配完整的匹配括號?

$text = "test 1 
      {blabla:database{test}} 
      {blabla:testing} 
      {option:first{A}.Value}{blabla}{option:second{B}.Value} 
      {option:third{C}.Value}{option:fourth{D}} 
      {option:fifth} 
      test 2 
     "; 

我需要得到所有{option ...}出這個字符串(5總共在這個字符串)。有些在其中有多個嵌套括號,有些則沒有。有些是在同一條線上,有些則不是。

我已經發現了這個正則表達式:

(\{(?>[^{}]+|(?1))*\}) 

所以下面的工作正常:

preg_match_all('/(\{(?>[^{}]+|(?1))*\})/imsx', $text, $matches); 

,這不是大括號內的文字被過濾掉了,但比賽還包括blabla -items ,我不需要。

有什麼辦法可以修改這個正則表達式,只包含option -items?

+0

這聽起來像一個文法分析工作。我有一次相關的問題。我很好奇,如果有人能完成這項工作! :) – hek2mgl

+0

可以有多少個嵌套大括號? – Flosculus

+1

[我對另一個問題的回答可能對你有用](http://stackoverflow.com/a/11468459/599857) – Leigh

回答

0

我修改了您的初始表達式以搜索附加了非空白字符(\ S *)的字符串'(option :)',並由大括號'{}'限制。

\{(option:)\S*\} 

鑑於你輸入的文字,下面的條目在regexpal匹配:

測試1

{布拉布拉:數據庫{測試}}

{布拉布拉:測試}

{option:first {A} .Value}{option:second {B} .Value}

{選項:第三{C}。價值}

{選項:第四{d}}

{選項:第五}

試驗2

+0

工作正常,但Leigh的答案也適用於A和B選項之間沒有空格時,所以我選擇了一個作爲答案。 – Dylan

0

試試這個正則表達式 - 它使用.NET正則表達式進行測試,它也可以與PHP一起使用:

\{option:.*?{\w}.*?} 

請注意 - 我假設你只有1對括號內,而且對裏面你只有1字母數字字符

0

如果你沒有在同一個多對括號水平這應該工作

/(\{option:(([^{]*(\{(?>[^{}]+|(?4))*\})[^}]*)|([^{}]+))\})/imsx 
0

這個問題是更適合適當的解析器,但是你可以用正則表達式,如果你真的想。

只要您沒有在其他選項中嵌入選項,這應該工作。

preg_match_all(
    '/{option:((?:(?!{option:).)*)}/', 
    $text, 
    $matches, 
    PREG_SET_ORDER 
); 

快速說明。

{option:    // literal "{option:" 
    (     // begin capturing group 
    (?:    // don't capture the next bit 
     (?!{option:). // everything NOT literal "{option:" 
    )*     // zero or more times 
)     // end capture group 
}      // literal closing brace 

var_dump與樣品輸入輸出編樣子:

array(5) { 
    [0]=> 
    array(2) { 
    [0]=> 
    string(23) "{option:first{A}.Value}" 
    [1]=> 
    string(14) "first{A}.Value" 
    } 
    [1]=> 
    array(2) { 
    [0]=> 
    string(24) "{option:second{B}.Value}" 
    [1]=> 
    string(15) "second{B}.Value" 
    } 
    [2]=> 
    array(2) { 
    [0]=> 
    string(23) "{option:third{C}.Value}" 
    [1]=> 
    string(14) "third{C}.Value" 
    } 
    [3]=> 
    array(2) { 
    [0]=> 
    string(18) "{option:fourth{D}}" 
    [1]=> 
    string(9) "fourth{D}" 
    } 
    [4]=> 
    array(2) { 
    [0]=> 
    string(14) "{option:fifth}" 
    [1]=> 
    string(5) "fifth" 
    } 
} 
+0

嗨Leigh,仍然存在一個小問題:如果兩個選項之間存在{...},則{...}部分包含在匹配中。 (請參閱修改的示例文本)以任何方式避免這種情況? – Dylan

+0

@Dylan它可以使用遞歸完成。請參閱我最初在評論中與您的問題相關的答案。你應該能夠適應這一點。 – Leigh