2009-12-13 28 views
2

我從wikipedia API中提取一個字符串,最初看起來像這樣: link text。我想剝離所有{{...}} 以及它們之間的所有內容(可以是任何類型的文本)。爲此,我考慮使用遞歸函數「preg_match」,「preg_replace」。 類似:PHP - 幫助我的基於REGEX的遞歸函數

function drop_brax($text) 
{ 
    if(preg_match('/{{(.)*}}/',$text)) 
    return drop_brax(preg_replace('/{{(.)*}}/','',$text)); 
    return $text; 
} 

的,因爲這樣的情況下,此功能將無法正常工作:

{{我喜歡mocachino {{但我也喜歡 香蕉}}和frutis}}

這將剝離{{和}}的第一次出現(並省略「和frutis}}」)之間的所有內容。 我該如何正確地做到這一點? (同時保持漂亮的遞歸形式)。

回答

6

嘗試這樣:

$text = '...{{aa{{bb}}cc}}...{{aa{{bb{{cc}}bb{{cc}}bb}}dd}}...'; 
preg_match_all('/\{\{(?:[^{}]|(?R))*}}/', $text, $matches); 
print_r($matches); 

輸出:

Array 
(
    [0] => Array 
     (
      [0] => {{aa{{bb}}cc}} 
      [1] => {{aa{{bb{{cc}}bb{{cc}}bb}}dd}} 
     ) 
) 

和簡短說明:

\{\{  # match two opening brackets 
(?:  # start non-capturing group 1 
    [^{}] # match any character except '{' and '}' 
    |  # OR 
    (?R) # recursively call the entire pattern: \{\{(?:[^{}]|(?R))*}} 
)   # end non-capturing group 1 
*   # repeat non-capturing group 1 zero or more times 
}}  # match two closing brackets 
+0

我試了一下,到目前爲止好,我要去給它一對夫婦更多的測試。 非常感謝! – Gal 2009-12-13 14:47:08

+0

不客氣Gal。 – 2009-12-13 14:50:20

0

有這個完全遞歸,您將需要一個解析器:

function drop_brax($str) 
{ 
    $buffer = NULL; 
    $depth = 0; 
    $strlen_str = strlen($str); 
    for($i = 0; $i < $strlen_str; $i++) 
    { 
     $char = $str[$i]; 

     switch ($char) 
     { 
      case '{': 
       $depth++; 
      break; 
      case '}': 
       $depth--; 
      break; 
      default: 
       $buffer .= ($depth === 0) ? $char : NULL; 
     } 
    } 
    return $buffer; 
} 

$str = 'some text {{ I like mocachino {{ but I also like banana}} and frutis }} some text'; 
$str = drop_brax($str); 
echo $str; 

輸出:

some text some text 
+0

我嘗試了你的建議和Bart K.'s,顯然他的表現更快。儘管如此,非常感謝您的幫助!我很感激。 – Gal 2009-12-13 14:52:21