如何使用PHP和preg_match_all将自关闭div转换为<div> </div>

时间:2015-12-19 23:37:55

标签: php regex

这是一个坏主意,但我需要继续前进,直到找到实际的解决方案。 Just spent 100 rep on a bounty to do so.

无论如何,我有一堆像这样的div:

<div id="videoPlayer0" class="videoPlayerPlacement" data-xml="video/cp_IV_a_1.xml"/>

ID中的数字和data-href一样可变。两者都需要保留。我需要这种形式的div:

<div id="videoPlayer0" class="videoPlayerPlacement" data-xml="video/cp_IV_a_1.xml"></div>

所以我的问题是如何使用preg_match_all实现上述转换(对于我们在HTML上使用它感到羞耻)。

一旦有人回答,任何人都会遇到这个问题: 不要在HTML上使用RegExp。搜索SO以找出原因。

2 个答案:

答案 0 :(得分:2)

一种可能的解决方案,不使用正则表达式,就是利用DOMDocument。在下面的代码中,输出通过管道传输到文本文件,以便您可以验证实际结果 - 我认为这或多或少是您尝试完成的。

<?php

    $strhtml='<div id="videoPlayer0" class="videoPlayerPlacement" data-xml="video/cp_IV_a_1.xml"/>
                <div id="videoPlayer1" class="videoPlayerPlacement" data-xml="video/cp_IV_a_2.xml"/>
                <div id="videoPlayer2" class="videoPlayerPlacement" data-xml="video/cp_IV_a_3.xml"/>';

    libxml_use_internal_errors( true );
    $dom = new DOMDocument;
    $dom->loadHTML( mb_convert_encoding( $strhtml, 'utf-8' ) );
    libxml_clear_errors();


    $body=$dom->getElementsByTagName('body')->item(0);
    $tmp=new DOMDocument;
    foreach( $body->childNodes as $div ){
        if( $div->nodeType==1 ){
             $clone = $div->cloneNode(true);    
             $tmp->appendChild($tmp->importNode($clone,true));
        }
    }


    file_put_contents( 'c:/temp/domdump.txt', $tmp->saveHTML() );
    $dom=null;
?>

答案 1 :(得分:1)

正则表达式解决方案:

$result = preg_replace('#<(div|textarea)([^>]*?)/>#si', '<$1$2></$1>', $temp);  

您可以根据需要将其他标记名称添加到竖线分隔列表中。

这不完美。以下内容不会被替换:

<div attrib = ">" />

以下内容将被错误地替换:

<script>
    if (s.indexOf('<div/>')==-1) { ...