2017-04-09 89 views
2

鑑於串$str = 'aa {{asd}} bla {{{888 999}} {555} 777 uiii {{-i {{qw{er}}';找最接近的雙括號

之間的所有事件需要得到最接近的開閉雙大括號之間的所有事件。

理想的結果:

  • ASD
  • QW ER {

如果嘗試:preg_match_all('#\{\{(.*?)\}\}#', $str, $matches);

電流輸出:

  • ASD
  • {888 999
  • -i {{{QW ER

不過,這些情況並不最接近雙大括號之間。

問題是:這是什麼適當的模式?

+0

將預期的輸出是多少,如果輸入中包含像'{{{a} b}}'? '{a} b'或'a} b'? –

+0

@Rawing - 在這種情況下預期的輸出:'a} b' –

回答

3

您可以使用此模式:

\{\{(?!\{)((?:(?!\{\{).)*?)\}\} 

這裏的技巧是使用負前瞻像(?!\{\{)避免匹配嵌套的括號。


\{\{  # match {{ 
(?!\{)  # assert the next character isn't another { 
(
    (?: # as few times as necessary... 
     (?!\{\{). # match the next character as long as there is no {{ 
    )*? 
) 
\}\}  # match }} 
1

Regex demo

正則表達式:(?<=\{{2})(?!\{)[\s\w\{]+(?=\}\})

(?=\}\})應該包含雙花括號前面

(?<=\{{2})應包含後面

0大括號

(?!\{)不應該包含大括號後面兩個一個大括號匹配

PHP代碼:

$str = 'aa {{asd}} bla {{{888 999}} {555} 777 uiii {{-i {{qw{er}}'; 
preg_match_all("/(?<=\{{2})(?!\{)[\s\w\{]+(?=\}\})/",$str,$matches); 
print_r($matches); 

輸出:

Array 
(
    [0] => Array 
     (
      [0] => asd 
      [1] => 888 999 
      [2] => qw{er 
     ) 

)