2013-06-01 138 views
1

好的,我有一个正则表达式,我试图用来匹配某些html文件中的某个模式。这里的的preg_match声明:PHP preg_match - 匹配html元素

preg_match('@<'.$htmlElementType.' id\s*=\s*"{{ALViewElement_'.$this->_elementId.'}}".*>[\s\S]*</'.$htmlElementType.'(>)@i', $htmlString, $newMatches, PREG_OFFSET_CAPTURE) 

需要明确的是,这种尝试的HTML元素的ID匹配{{ALViewElement _ *}},但它也需要结束自己与关闭标签,例如,如果$ htmlElementType是“section”,它将以“/ section>”结尾。

如果我的HTML看起来就像这样加任何东西,它按预期工作:

<section id="{{ALViewElement_resume}}"> 
      <!--{{RESUME_ADD_CHANGE_PIECE}}--> 
      <!--{{RESUME}}--> 
     </section> 

问题是,当我们在HTML有部分元素以后,它也有一个关闭/节>。例如:

<section id="{{ALViewElement_resume}}"> 
      <!--{{RESUME_ADD_CHANGE_PIECE}}--> 
      <!--{{RESUME}}--> 
     </section> 
     <div> 

     </div> 
     <section> 
      HEY THIS IS ME 
     </section> 

在这种情况下,完整的马赫是上面的一切。但我希望它停止在那开启我的第一个。这很重要,因为稍后在我的代码中,我需要结尾标记中最后一个>的位置。

任何想法如何我可以改变这个正则表达式一点点?

感谢您的帮助!

+0

**不要使用正则表达式来解析HTML **。你不能用正则表达式可靠地解析HTML,你将面临悲伤和挫折。只要HTML从你的期望改变,你的代码就会被破坏。有关如何使用已经编写,测试和调试的PHP模块正确解析HTML的示例,请参阅http://htmlparsing.com/php。 –

回答

2

是,只需使用一个ungreedy量词:

preg_match('@<'.$htmlElementType.' id\s*=\s*"{{ALViewElement_'.$this->_elementId.'}}".*?>[\s\S]*?</'.$htmlElementType.'(>)@i', $htmlString, $newMatches, PREG_OFFSET_CAPTURE) 

另一种方式:与DOM文档:

$html = <<<LOD 
<section id="{{ALViewElement_resume}}"> 
     <!--{{RESUME_ADD_CHANGE_PIECE}}--> 
     <!--{{RESUME}}--> 
</section> 
<div> 

</div> 
<section> 
    HEY THIS IS ME 
</section> 
LOD; 
$doc= new DOMDocument(); 
@$doc->loadHTML($html); 
$node = $doc->getElementById("{{ALViewElement_resume}}"); 

$docv = new DOMDocument(); 
$docv->appendChild($docv->importNode($node, TRUE)); 
$result = $docv->saveHTML(); 
echo htmlspecialchars($result); 
+0

太棒了。甚至不知道这样的事情存在。谢谢! – user1513171