【问题标题】:How to remove text between tags in php?如何删除php中标签之间的文本?
【发布时间】:2010-11-24 14:46:26
【问题描述】:

尽管使用 PHP 多年,但我从未真正学会如何使用表达式正确截断字符串……这让我很反感!

谁能帮我截断这个?我需要从 url 中去掉文本部分,转

<a href="link.html">text</a>

进入

<a href="link.html"></a>

【问题讨论】:

    标签: php regex string


    【解决方案1】:
    $str = preg_replace('#(<a.*?>).*?(</a>)#', '$1$2', $str)
    

    【讨论】:

    • 虽然这可行,但您通常不希望使用正则表达式解析 HTML。卡里姆的回答可能更可取。
    【解决方案2】:

    使用SimpleHTMLDom

    <?php
    // example of how to modify anchor innerText
    include('simple_html_dom.php');
    
    // get DOM from URL or file
    $html = file_get_html('http://www.example.com/');
    
    //set innerText to null for each anchor
    foreach($html->find('a') as $e) {
        $e->innerText = null;
    }
    
    // dump contents
    echo $html;
    ?>
    

    【讨论】:

    • 无意冒犯,但是这个答案是 8 年的,实际上没有人注意到这个答案是不正确的并且不起作用。简单地回显$html 时,foreach 循环无效。不敢相信这得到了如此多的赞成票,而且没有人实际测试过。
    【解决方案3】:

    考虑到您可能想与其他hrefs 重复使用,这样的事情怎么样:

    $str = '<a href="link.html">text</a>';
    $result = preg_replace('#(<a[^>]*>).*?(</a>)#', '$1$2', $str);
    var_dump($result);
    

    这会得到你:

    string '<a href="link.html"></a>' (length=24)
    

    (我在考虑你在 OP 中打错字了?)


    如果您不需要匹配任何其他href,您可以使用类似:

    $str = '<a href="link.html">text</a>';
    $result = preg_replace('#(<a href="link.html">).*?(</a>)#', '$1$2', $str);
    var_dump($result);
    

    这也会让你:

    string '<a href="link.html"></a>' (length=24)
    


    作为旁注:对于更复杂的 HTML,不要尝试使用正则表达式:它们在这种简单的情况下工作得很好,但对于现实生活中的 HTML 部分,它们并没有真正的帮助,一般来说:HTML 不是非常“常规”“足够”被正则表达式解析。

    【讨论】:

      【解决方案4】:

      您可以将 substring 与 stringpos 结合使用,尽管这不是 一个非常好的方法。

      检查:PHP Manual - String functions

      另一种方法是编写一个正则表达式来匹配您的条件。 但是为了快速解决你的问题,字符串函数会做......

      编辑:我低估了观众。 ;) 继续使用正则表达式... ^^

      【讨论】:

        【解决方案5】:

        您不需要自己捕获标签。只需定位标签之间的文本并将其替换为空字符串。超级简单。

        Demo of both techniques

        代码:

        $string = '<a href="link.html">text</a>';
        echo preg_replace('/<a[^>]*>\K[^<]*/', '', $string);
        // the opening tag--^^^^^^^^  ^^^^^-match everything before the end tag
        //                          ^^-restart fullstring match
        

        输出:

        <a href="link.html"></a>
        

        或者在链接文本包含&lt; 的边缘情况下,使用这个:~&lt;a[^&gt;]*&gt;\K.*?(?=&lt;/a&gt;)~

        这避免了使用惰性量词、重新启动\K 和“前瞻”的捕获组的开销。


        年长且聪明:

        如果你正在解析有效的 html,你应该使用 dom 解析器来保证稳定性/准确性。正则表达式是 DOM 无知的,所以如果标签属性值包含 &gt;,我的 sn-p 将失败。

        作为一个非常适合提供一些上下文的 domdocument 解决方案:

        $dom = new DOMDocument;
        $dom->loadHTML($string, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); // 2nd params to remove DOCTYPE);
        $dom->getElementsByTagName('a')[0]->nodeValue = '';
        echo $dom->saveHTML();
        

        【讨论】:

          【解决方案6】:

          只使用strip_tags(),这样会去掉标签,只在它们之间留下想要的文本

          【讨论】:

          • 这与 MrFidge 想要做的完全相反。他想删除标签之间的文本,但保留标签。