2013-03-18 48 views
2

我想了解更多關於正則表達式,在這種情況下,您可以在正則表達式中做遞歸。遞歸正則表達式不匹配模板塊

我試圖匹配{foreach $VAR} ... {/foreach}的嵌套塊。但由於某種原因,我的正則表達式不匹配,我不明白爲什麼。

我希望這裏的任何人都能對此有所瞭解。我是而不是對快速正則表達式感興趣。但更重要的是爲什麼我的正則表達式沒有達到我期望的水平。究竟發生了什麼?

這是我的代碼有:

<?php 
$str = 'start of text 
{foreach $ABC} 
    in 1st loop 
    {foreach $XYZ} 
    in 2nd loop 
    {/foreach} 
{/foreach} 
some other stuff'; 

if (preg_match ('#{foreach \$.*?}((?!foreach)|(?R))*{/foreach}#', $str, $matches)) 
{ 
    print_r($matches); 
} 
else 
{ 
    echo 'No match'; 
} 

這裏是我的正則表達式的作爲如何,我認爲它的工作呢擊穿:

{foreach \$  #match literally "{foreach $" 
.*?}   #followed by any character ending with a '}' 
(    # start a group 
    (?!foreach) # match any character, aslong as it's not the sequence 'foreach' 
    |    # otherwise 
    (?R)   # do a recursion 
)    # end of group 
*    # match 0 or more times with a backtrace... 
{/foreach}  # ...backtracing until you find the last {/foreach} 

這就是我想正則表達式的作品。但顯然情況並非如此。所以我的問題是,我的解釋在哪裏?

可以玩弄此驗證碼:http://codepad.viper-7.com/508V9w


只是爲了澄清。

我試圖獲取每個foreach塊的內容。所以,在我的情況:

arr[0] => in 1st loop 
     {foreach $XYZ} 
     in 2nd loop 
     {/foreach} 
arr[1] => in 2nd loop 

OR -

arr[0] => {foreach $ABC} 
     in 1st loop 
     {foreach $XYZ} 
     in 2nd loop 
     {/foreach} 
    {/foreach} 
arr[1] => {foreach $XYZ} 
     in 2nd loop 
     {/foreach} 

要麼會做得很好。

+0

這是否圖案編譯?在正則表達式中,{&和}是特殊字符。 – 2013-03-18 15:04:11

+0

@KennethK。是的,它似乎編譯好。當我逃避他們時,我也看不出有什麼不同。但是,從現在開始,或許對我來說這樣做更好。 – w00 2013-03-18 15:18:16

回答

0

首先,.確實與匹配,但是默認情況下只有換行符。爲了使它與換行符匹配,您必須設置修飾符s

其次,你在這裏使用斷言:((?!foreach)|(?R))*,但沒有實際的字符匹配。量詞之前至少需要一個點或其他東西。

#{foreach \$.*?}((?!foreach)|(?R)).*{/foreach}#s給出了下面的結果與你的測試文本:

Array 
(
    [0] => {foreach $ABC} 
    in 1st loop 
    {foreach $XYZ} 
    in 2nd loop 
    {/foreach} 
{/foreach} 
    [1] => 
) 
+0

我忘了在我的文章中添加's'修飾符。但正如你可以看到它在* codepad *頁面中那樣。通過在星號之前加上一個'.',它確實給了我你顯示的結果。但是它怎麼沒有捕捉到內部的'{foreach $ XYZ}'?我希望這個正則表達式能夠做到這一點。也不知道空匹配來自'[1]'哪裏,有什麼想法? – w00 2013-03-18 14:56:52

+0

沒有捕獲,因爲您沒有在子模式周圍設置適當的括號。 – CBroe 2013-03-18 14:59:56