【问题标题】:How can I strip_tags except anchors with remote links?除了带有远程链接的锚点之外,我如何才能剥离标签?
【发布时间】:2014-05-06 21:42:12
【问题描述】:

如何用它的链接替换标签的内容

$str = 'This <strong>string</strong> contains a <a href="/local/link.html">local link</a>
        and a <a href="http://remo.te/link.com">remote link</a>';
$str = strip_tags($str,'<a>'); // strip out the <strong> tag
$str = ?????? // how can I strip out the local link anchor tag, but leave the remote link?
echo $str;

期望的输出:

This string contains a local link and a <a href="http://remo.te/link.com">remote link</a>

或者,更好,用它的 url 替换远程链接的内容:

This string contains a local link and a http://remo.te/link.com

我怎样才能达到最终的输出?

【问题讨论】:

  • 看起来你可能想学习一些正则表达式:)
  • @JayBlanchard,哈哈。我终于弄明白了。

标签: php replace preg-replace str-replace strip-tags


【解决方案1】:

替换你的remotely linked anchor with the URL:

<a href="(https?://[^"]+)">.*?</a>
$1

要删除anchor around a local URL

<a href="(?!https?://)[^"]+">(.*?)</a>
$1

解释

这两个表达式都匹配 &lt;a href=""&gt;&lt;/a&gt;。然后,第一个将匹配捕获组中的远程 URL(http、可选的s:// 以及结束" 之前的所有内容),我们可以使用$1 引用该捕获组。第二个表达式将匹配不以之前使用的协议开头的任何内容,然后将链接的实际文本捕获到$1

请注意,正则表达式并不是解析 HTML 的最佳解决方案,因为 HTML is not a regular language。但是,您的用例似乎足够“简单”,我们可以制作正则表达式。此不会&lt;a href=''&gt;&lt;/a&gt;&lt;a href="" title=""&gt;&lt;/a&gt; 之类的链接一起使用,但它可以扩展以允许这些用例(因此我之前的 HTML 不是常规)。


PHP

$str = 'This <strong>string</strong> contains a <a href="/local/link.html">local link</a> and a <a href="http://remo.te/link.com">remote link</a>';
$str = strip_tags($str,'<a>');

$str = preg_replace('~<a href="(https?://[^"]+)".*?>.*?</a>~', '$1', $str);
$str = preg_replace('~<a href="(?!https?://)[^"]+">(.*?)</a>~', '$1', $str);

echo $str;
// This string contains a local link and a http://remo.te/link.com

【讨论】:

  • 如果您需要我更深入地解释我的表达方式,请告诉我。
【解决方案2】:

注意: HTML 不是正则语言,无法使用正则表达式真正解析。请改用 DOM 解析器。

但是,如果您完全确定格式,则可以使用正则表达式。整个任务只需要分成两步:

/* Replace relative URIs with their anchor text */
$str = preg_replace('#<a[^>]*href="(?=/)[^"]+">([^<]+)</a>#', '$1', $str); 

/* Replace absolute URIs with their href */
$str = preg_replace('#<a[^>]*href="((?!/)[^"]+)">[^<]+</a>#', '$1', $str);

当然,如果其中一个属性值包含&gt;,这将失败。如果您关心这些极端情况,使用 DOM 解析器将是正确的解决方案。

输出:

This string contains a local link
        and a http://remo.te/link.com

Demo

【讨论】:

    【解决方案3】:

    这可以通过使用类 DOMDocument 来实现

    例如:

    $doc = new DOMDocument('1.0', 'UTF-8');         
    $doc->loadHTML($str);
    

    以及进一步处理该方法的链接:

    $doc->getElementsByTagName('a')
    

    【讨论】:

      【解决方案4】:

      我是这样解决的:

      $str = 'This <strong>string</strong> contains a <a href="/local/link.html">local link</a> and a <a href="http://remo.te/link.com">remote link</a>';
      $str = preg_replace('/<a [^>]*?href="(http:\/\/[A-Za-z0-9\\.:\/]+?)">([\\s\\S]*?)<\/a>/','\\1', $str); // strip remote links and replace with href
      $str = strip_tags($str); // strip any local links
      echo $str;
      

      结果:

      This string contains a local link and a http://remo.te/link.com
      

      【讨论】:

        【解决方案5】:

        如果这个字符串不是动态创建的,并且你知道data href,你可以试试

        $str = 'This <strong>string</strong> contains a <a href="/local/link.html">local link</a>
                and a <a href="http://remo.te/link.com">remote link</a>';
        $str = str_replace(array('<a href="/local/link.html">', '</a>'), ' ' , $str);       
        $str = strip_tags($str,'<a>'); // strip out the <strong> tag
        echo $str;
        

        结果:

        This string contains a  local link and a <a href="http://remo.te/link.com">remote link</a>
        

        【讨论】:

          【解决方案6】:

          简单的 html dom 可能是你最好的选择:

          $doc = str_get_html($html);
          
          foreach($doc->find('a') as $a){
            $a->outertext = preg_match('/^http/', $a->href) ? $a->href : $a->text();
          }
          
          echo $doc;
          

          【讨论】:

            【解决方案7】:

            就我的情况而言,我需要一些东西来替换锚标记,但保留锚标记的 链接内部文本。因此,我修改了@Sam 的解决方案,并为内部文本添加了一个额外的匹配组。

            $text = strip_tags($html,'<a>');
            $text = preg_replace('~<a href="(https?://[^"]+)".*?>(.*?)</a>~', '$2 ($1)', $text);
            

            对于&lt;a href="https://stackoverflow.com"&gt;Stackoverflow&lt;a&gt;,上面的代码将输出Stackoverflow (https://stackoverflow.com)

            【讨论】:

              猜你喜欢
              • 2023-03-17
              • 2022-06-11
              • 2014-04-17
              • 2014-11-11
              • 2010-09-07
              • 1970-01-01
              • 2015-05-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多