2009-09-20 50 views
0

我試圖匹配模板文件中的一組標籤。不過,我希望標籤能夠嵌套在其本身中。PHP的正則表達式匹配遞歸地

我的正則表達式如下:(有/秒)

<!-- START (.*?) -->(.*?)<!-- END \\1 --> 

標記示例:

<!-- START yList --> 
    y:{yList:NUM} | 
    <!-- START xList --> 
    x:{xList:NUM} 
    <!-- END xList --> 
    <!-- CARET xList --> 
    <br> 
<!-- END yList --> 
<!-- CARET yList --> 

現在比賽的結果將是:

比賽0:

組(0)(整場比賽)

<!-- START yList --> 
y 
<!-- START xList --> 
    x 
<!-- END xList --> 
<!-- CARET xList --> 
<br> 
<!-- END yList --> 

基團(1)

yList 

組(2)

y 
<!-- START xList --> 
    x 
<!-- END xList --> 
<!-- CARET xList --> 
<br> 

欲2個匹配,而不是1明顯,嵌套標籤集不匹配。這是可能的正則表達式,或者我應該保持regexing組(2)的結果,直到我發現沒有新的匹配?

回答

0

你可以做這樣的事情:

$parts = preg_split('/(<!-- (?:START|END|CARET) [a-zA-Z][a-zA-Z0-9]* -->)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE); 
$tokens = array(); 
$isTag = isset($tokens[0]) && preg_match('/^<!-- (?:START|END|CARET) [a-zA-Z][a-zA-Z0-9]* -->$/', $tokens[0]); 
foreach ($parts as $part) { 
    if ($isTag) { 
     preg_match('/^<!-- (START|END|CARET) ([a-zA-Z][a-zA-Z0-9]*) -->$/', $token, $match); 
     $tokens[] = array($match[1], $match[2]); 
    } else { 
     if ($token !== '') $tokens[] = $token; 
    } 
    $isTag = !$isTag; 
} 
var_dump($tokens); 

這會給你的代碼的結構。

5

正則表達式不適合解析任意深度的樹結構。根據你使用的正則表達式,這可能是可能的,但不推薦 - 它們很難閱讀,也很難調試。

我建議改爲編寫一個簡單的解析器。你要做的就是分解你的文字轉換爲一組的可能令牌它們可以分別通過簡單的正則表達式來定義,如:

START_TOKEN = "<!-- START [A-Za-z] -->" 
END_TOKEN = ... 
HTML_TEXT = ... 

遍歷你的字符串,只要你符合這些令牌,將他們拉在字符串之外,並將它們存儲在單獨的列表中。請確保在執行此操作時保存標記內的文本(如果有)。

然後您可以遍歷您的令牌列表,並根據令牌類型創建節點的嵌套樹結構,每個結構包含1)原始標記的文本和2)子節點列表。

如果這看起來太複雜,您可能需要查看一些解析器教程。

+0

有趣。你能推薦任何解析教程嗎? –