PHP:删除多个子标记

时间:2017-04-27 04:21:10

标签: php regex

<div class="article_content">
 <p>&nbsp;</p>
 <p>&nbsp;</p>
 <p>&nbsp;</p>
 <p>&nbsp;</p>

<ul>
 <li>UPDATE mytable SET tax = amount</li>
</ul>
<p>after you can remove it</p>
<p>&nbsp;</p> <!-- dot want to delete this line -->
<ul><li>ALTER TABLE mytable DROP COLUMN amount;</li>
</ul>
</div>

我希望删除所有<p>&nbsp;</p>,直到第一个ul<p>.... content .... </p>之类的任何标记出现。

如果我要使用这个str_replace("<p>&nbsp</p>","",$string);,它将删除字符串中的所有空行。但我想在第一次出现之前删除行。

6 个答案:

答案 0 :(得分:0)

我认为你应该尝试使用jQuery而不是在PHP中执行它,因为jQuery是DOM遍历和操作的最佳库。

请尝试以下代码段,希望这对您更好。

&#13;
&#13;
$(function() {
  $(".article_content p").each(function() {
    var self = $(this),
      arr = []; // get all blank elements in array
    if (self.text().trim().length == 0 // check its length
      &&
      (self.prev().text().trim().length === 0 || // checking previous element is blank or not
        self.next().text().trim().length === 0)) { // checking next element is blank or not
      arr.push(self); // if all are blank then add in array
    }
    // now remove all elements
    $(arr).each(function() {
      $(this).remove()
    });
  });
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="article_content">
  <p>&nbsp;</p>
  <p>&nbsp;</p>
  <p>&nbsp;</p>
  <p>&nbsp;</p>
  <ul>
    <li>UPDATE mytable SET tax = amount</li>
  </ul>
  <p>after you can remove it</p>
  <p>&nbsp;</p>
  <!-- dot want to delete this line -->
  <ul>
    <li>ALTER TABLE mytable DROP COLUMN amount;</li>
  </ul>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

这可以通过客户端语言(如jQuery

)实现
  1. .prevAll(): - 获取匹配元素集中每个元素的前一个兄弟。如果提供了选择器,则仅当它与该选择器匹配时,它才会检索前一个兄弟。
  2. .first(): - 将匹配元素集减少到集合中的第一个元素。
  3. 示例如下所示: -

    $(function() {
    var pTag = $( "ul" ).first().prevAll('p');
    pTag.remove();
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <div class="article_content">
     <p>&nbsp;</p>
     <p>&nbsp;</p>
     <p>&nbsp;</p>
     <p>&nbsp;</p>
    
    <ul>
     <li>UPDATE mytable SET tax = amount</li>
    </ul>
    <p>after you can remove it</p>
    <p>&nbsp;</p> <!-- dot want to delete this line -->
    <ul><li>ALTER TABLE mytable DROP COLUMN amount;</li>
    </ul>
    </div>

答案 2 :(得分:0)

在数据库中插入数据时也可以这样做。 每次按Enter键时,默认设置都会创建一个段落元素: 更改您的CKEDITOR设置默认为true。

config.autoParagraph = false;

您也可以将输入模式设置为BR和其他相关的

config.enterMode = CKEDITOR.ENTER_BR;

Read this same question

答案 3 :(得分:0)

希望这可以帮助你,在删除包含&nbsp;的所有子节点时,直到新标记出现一些内容为止。

Try this code snippet here

<?php
ini_set('display_errors', 1);
header("Content-Type:text/html; charset=UTF-8");
$string= <<<HTML
<html><body><div class="article_content">
 <p>&nbsp;</p>
 <p>&nbsp;</p>
 <p>&nbsp;</p>
 <p>&nbsp;</p>

<ul>
 <li>UPDATE mytable SET tax = amount</li>
</ul>
<p>after you can remove it</p>
<p>&nbsp;</p> <!-- dot want to delete this line -->
<ul><li>ALTER TABLE mytable DROP COLUMN amount;</li>
</ul>
</div></body></html>
HTML;
$object = new DOMDocument();
$object->loadHTML($string);
$remove=array();
$nodelist=$object->getElementsByTagName("div")->item(0)->childNodes;
foreach($nodelist as $node)
{
    if($node instanceof DOMElement)
    {
        if($node->tagName=='p' && str_replace("&nbsp;","",htmlentities($node->textContent))=="")
        {
            $remove[]=$node;
        }
        else
        {
            break;
        }
    }
}
foreach($remove as $node)
{
    $node->parentNode->removeChild($node);
}
echo $object->saveHTML();

答案 4 :(得分:0)

// Press F11 to toggle full screen editting (Ctrl+⌘+F on Mac OS).
// Press Ctrl+Shift+F to format code.
$string = '
<div class="article_content">
 <p>&nbsp;</p>
 <p>&nbsp;</p>
 <p>&nbsp;</p>
 <p>&nbsp;</p>

<ul>
 <li>UPDATE mytable SET tax = amount</li>
</ul>
<p>after you can remove it</p>
<p>&nbsp;</p> <!-- dot want to delete this line -->
<ul><li>ALTER TABLE mytable DROP COLUMN amount;</li>
</ul>
</div>
';
$remove=array();
$dom = new DOMDocument;
$dom->loadHTML($string);
//$newstring = $dom->getElementsByTagName('<p>&nbsp;</p>')->item(4);
$newstring = $dom->getElementsByTagName('p');
foreach($newstring as $stringnode)
{
        if($stringnode->tagName=='p' && str_replace("&nbsp;","",htmlentities($stringnode->textContent))=="")
        {
            $remove[]=$stringnode;
        }
        else
        {
            break;
        }
}

foreach($remove as $node)
{

        $node->parentNode->removeChild($node);

}
echo $dom->saveHTML();

答案 5 :(得分:0)

在使用HTML结构时使用DOM是一种很好的做法。但在这个具体案例中,与其他答案不同,我更喜欢正则表达式:

d1.resolve(LoadSideBarContent(url));


var d1 = $.Deferred();

            $.when(d1).then(function () {
                alert('loaded');
            });

            d1.resolve(LoadSideBarContent(url)); //<-- with what value you want to resolve  the Deffered object ?

<script type="text/javascript">
    function LoadSideBarContent(url) {
        $("#SideBarContent").html();    //<---What's this ?
        $("#SideBarContent").load(url);
    };
</script>

Live demo

正则表达式解释:

(?s)<(?:(?:ul|p>(?:(?!&nbsp;)|[^>]*</p>\s*(*ACCEPT)))).*\K

PHP代码:

(?s)    # Enable DOTALL modifier
<       # Match a `<`
    (?:     # Start of non-capturing group (a)
        (?: # Start of NCG (b)
            ul  # Match `ul`
            |   # OR
            p>  # Match `p>`
            (?: # Start of NGC (c)
                (?!&nbsp;)   # Shouldn't be followed by `&nbsp;`
                |            # OR
                [^>]*</p>\s* # Otherwise match whole `p` tag
                (*ACCEPT)    # Force engine to end current matching attempt
            )   # End of NGC (c)
        )   # End of NGC (b)
    ).*\K   # End of NGC (a), match up to the end of input string and throw it away

PHP Live demo