【问题标题】:Group specific HTML-tags into sections将特定的 HTML 标记分组到部分中
【发布时间】:2014-02-18 19:41:50
【问题描述】:

我有一个带有这样标记的字符串:

<h3></h3>
<p><span><strong></strong></span></p>
<p></p>
<div></div>
<p></p>
<p></p>
<img />
<div></div>

我想将所有标签分组。但是 except div 和 imgs。这两个标签应该在它们自己的部分中,并且不应该组合在一起。所以结果应该是这样的:

<section>
    <h3></h3>
    <p><span><strong></strong></span></p>
    <p></p>
</section>

<section>
    <div></div>
</section>

<section>
    <p></p>
    <p></p>
</section>

<section>
    <img />
</section>

<section>
    <div></div>
</section>

我怎样才能用 php 做到这一点?

【问题讨论】:

  • 没有正则表达式可以做到这一点...stackoverflow.com/questions/1732348/… 正则表达式不是适合这项工作的工具。你需要一个 XML 解析器。
  • 好的,谢谢。你有什么好的给我吗?
  • 我对 PHP 的 XML 解析没有任何直接经验。谷歌搜索 PHP XML 解析应该会让你很接近。
  • 如果使用 PHP,SimpleXML 就是你想要的。
  • DOMDocument

标签: php html regex xml-parsing


【解决方案1】:

假设你给的内容只在body里面,你可以这样用:

$data = <<<'LOD'
<h3></h3>
<p><span><strong></strong></span></p>
<p></p>
<div></div>
<p></p>
<p></p>
<img />
<div></div>
<p><p><img /></p></p>
<!-- <img /> -->
<div> <div> </div> </div>
LOD;

$pattern = <<<'LOD'
~
(?(DEFINE)
    (?<comment> <!-- .*? --> )
    (?<cdata> \Q<![CDATA[\E .*? ]]> )
    (?<script_style> <s(cript|tyle)\b .*? </s\g{-1}> )
    (?<skip_list>
        \g<comment> | \g<cdata> | \g<script_style> 
    )

    (?<tag>
        <code\b .*? </code> | \g<self_closing_tag> |
        <(\w++) [^>]*+>
        (?> [^<]++ | \g<skip_list> | \g<tag> )*+
        </\g{-1}> 
    )
    (?<self_closing_tag> <(?:img|[bh]r)\b [^>]*+> )
    (?<other_tag> (?!<(?:img|div)\b) \g<tag>  )

    (?<div> (?=<div\b) \g<tag>)
    (?<img> (?=<img\b) \g<self_closing_tag>)

    (?<other_tags> \g<other_tag> (?>[^<]*+ \g<other_tag>)*+ )
)

\g<skip_list> (*SKIP)(*FAIL)
|
\g<div> | \g<img> | \g<other_tags>  

~xsi
LOD;


$result = preg_replace($pattern, "\n<section>\n$0\n</section>", $data);

echo htmlspecialchars($result);

【讨论】:

  • 嘿伙计,这就像一个魅力。但有一件事:是否可以使用 html 中的代码标签,如下所示:&lt;pre&gt;&lt;code&gt;$hello = here_is_code();&lt;/code&gt;&lt;/pre&gt;
  • 不,前置标签周围有一个 div 包装器。但目前,hole 脚本无法使用代码标签中的代码。
  • 为什么 php 在实际调用某些东西之前需要 (?(DEFINE) .. )?好像这个群体必须首先存在。 Perl 让你可以把它放在任何地方。
  • @sln: 你也可以在 PHP 中把它放在你想要的地方。这只是我自己的写作惯例。
  • 我在 php_sandbox 站点中运行了一些测试代码,它只在顶部使用它。哦,好吧,不过我只试过一次。 .. 顺便说一句,这是很好的代码!
猜你喜欢
  • 1970-01-01
  • 2012-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多