$str = '
其他文本其他文本<div>仅单层</div></div>(注意:后面多一个</div>)
其他文本其他文本其他文本
<div>外层
    <div>中层
        <div>内层</div>
    </div>
</div>
其他文本<font>外层<span>里层</span></font>其他文本其他文本……
';
$re = ???
preg_match_all($re,$str,$matches);
print_r($matches[0]);
希望结果是:
array(
    0 => <div>仅单层</div>
    1 => <div>外层
    <div>中层
        <div>内层</div>
    </div>
</div>
    2 => <font>外层<span>里层</span></font>
)往往出来的第一个匹配是:<div>仅单层</div></div>,这不是想要的 <div>仅单层</div>国内介绍正则递归的资料很少。希望高手顺便解释一下递归用法。

解决方案 »

  1.   


    其实就是正则递归,比如(?1),表示递归引用第一个括号的内容。我大概知道,但还是写不好。搜索老帖,找到一位高人写的如下正则,作用是匹配一个*.php文件中的每个类class的内容。$re = "`class[^{]+(\{([^{}]*|(?1))*\})`s";谁能分析一下用法?
      

  2.   

    <?php
    //*
    $str = '
    其他文本其他文本 <div>仅单层 </div> </div>(注意:后面多一个 </div>)
    其他文本其他文本其他文本
    <div>外层
         <div>中层
             <div>内层 </div>
         </div>
    </div>
    其他文本 <font>外层 <span>里层 </span> </font>其他文本其他文本……
    '; 
    $re = "#<[a-z]([^ >]+)[^<>]*>([^<>]*|(?R))*</[^<>]+>#is";
    //*/preg_match_all($re,$str,$matches);
    print_r($matches[0]); 
    ?>
      

  3.   

    ice_berg16 的很强大,收藏学习了!可以解决很多问题查了一下,
    $re = "`class[^{]+(\{([^{}]* ¦(?1))*\})`s"; 
    也是ice_berg16 写的,class[^{]+     以class开始,后跟非{一个或多个(\{([^{}]* ¦(?1))*\})分组
    \{([^{}]* ¦(?1))*\} 匹配{}以内容
    ([^{}]* ¦(?1))* 中的内容,并递归,这具看不明白,不知为何要用(?1),这个指的递归哪个,第一个分组捕获?另外(?1)*后面有个*也不明白有什么用手册上只有一小段英文介绍
      

  4.   

    楼主查一下手册吧!Perl正则规范里有一段说明!仔细看一下!
    ice_berg16很强大!
      

  5.   


    <?php
    $str = '
    其他文本其他文本 <div>仅单层 </div> </div>(注意:后面多一个 </div>)
    其他文本其他文本其他文本
    <div>外层
         <div>中层
             <div>内层 </div>
         </div>
    </div>
    # 这是另一种情况 
    # start 闭合错误
    <div>外层
         <div>中层
             <div>内层 </div>
         </div>
    </font> 
    # end 闭合错误
    其他文本 <font>外层 <span>里层 </span> </font>其他文本其他文本……
    '; 
    $re = "/<([a-z]+)[^>]*>([^<>]|(?R))*<\/\\1>/is";
    preg_match_all($re,$str,$matches);
    print_r($matches[0]);
    echo PHP_VERSION; // 5.2.5
    ?>嘿嘿~被抢先了一步,整理一下~套点分~
      

  6.   

    ice_berg16,能否详细说明递归的用法?$re = "#<[a-z]([^ >]+)[^<>]*>([^<>]*|(?R))*</[^<>]+>#is";([^<>]*|(?R))* 这里没看懂。
      

  7.   

    能否用来去掉UBB代码?UBB代码经常可能有嵌套:$str = '
    [normal text here]加粗红色[color=#0000FF]蓝色红色[/color][/not match]
    ';
    请问能否一次性去掉配对的UBB代码?$re = ?
    $result = preg_replace($re, $replace, $str);
    print_r($result);结果为:
    [normal text here]加粗红色蓝色红色[/not match]