【问题标题】:Strip anchors down to their contents, only if the anchor's URL contains仅当锚的 URL 包含
【发布时间】:2010-03-12 07:25:20
【问题描述】:

有没有人知道 PHP 中有一个正则表达式函数来去除其内容的锚点,只有当锚点的 href 属性包含特定文本时?

例如,我有一个 HTML 页面,整个页面都有链接。但我只想删除 URL 中包含“yahoo”的锚点。所以<a href="http://pages.yahoo.com/page1">Example page</a> 将变为:示例,而 HTML 中不包含“yahoo”的其他锚点将被单独保留。

【问题讨论】:

  • 对不起托尼,会变成什么?

标签: php html regex tags anchor


【解决方案1】:

首先,这不是正则表达式问题(或者至少不应该是)。 PHP 带有一个 HTML 解析器,所以我强烈推荐使用它。

当您使用它时,您只需遍历所有锚标记,检查 href 属性并在必要时进行修改,然后将其保存回 HTML。例如:

$dom = new DOMDocument;
$dom->loadHTML($html); // $html as a string
$anchors = $dom->getElementsByTagName('a');
for ($i=0; i<$anchors->length; $i++) {
  $item = $anchors->item[$i];
  $href = $item->getAttribute('href');
  $host = parse_url($href, PHP_URL_HOST);
  if (stripos($host, 'yahoo') !== false) {
    $item->parentNode->removeChild($item);
  }
}
$html = $dom->saveHTML();

在此处使用parse_url() 是可选的。您可以简单地检查属性值是否在其中的任何位置包含“yahoo”,而无需仅提取主机名。

显着比针对同一问题的任何基于正则表达式的解决方案更好、更健壮。

【讨论】:

  • -1|如果他要永久更改文件,他最好使用功能强大的编辑器来完成这项工作。
  • 好的,您的解决方案看起来不错,但还有 2 个问题。至于性能和内存使用,与正则表达式解决方案相比,它的效率如何?似乎这个选项会有更多的开销。另外,我还没有对此进行测试,但是在您的示例中,您似乎只是在修改锚的 href 属性,而不是剥离其标签的锚。我仍然不知道正则表达式是什么,但我认为 preg_replace 可以解决问题。
  • @Tony 如果您将此作为渲染页面的一部分,那么网络延迟可能是一个更大的工厂,除非您在非常大的文档上执行此操作。内存使用基本上是文档大小的线性函数,处理时间也是如此,因此可以很好地扩展。如果您陷入过多的回溯场景,正则表达式可能会更加不可预测。
  • @Tony 也更改为删除该元素。
  • 感谢 cletus,但我仍然认为您没有正确阅读问题。我只想剥离标签并保留锚的内容,前提是href包含雅虎。这是另一个例子:&lt;a href="http://books.yahoo.com"&gt;This Text&lt;/a&gt; -> This Text
【解决方案2】:

试试这个功能。

public function stripAnchorTags($html, $ignore_host = false, $charset="UTF-8"){
        $dom = new DOMDocument;
        $dom->loadHTML('<?xml version="1.0" encoding="'.$charset.'"?>'.$html); // $html as a string
        $anchors = $dom->getElementsByTagName('a');
        $length = $anchors->length;
        for($i=0; $i<$length; $i++){
            $item = $anchors->item(0);
            $href = $item->getAttribute('href');
            $host = parse_url($href, PHP_URL_HOST);
            if(!$ignore_host || stripos($host, $ignore_host) === false) {
                $item->parentNode->replaceChild($dom->createTextNode($href),$item);
            }
        }
        return preg_replace('/^<!DOCTYPE.+?>/', '', str_replace( array('<html>', '</html>', '<body>', '</body>'), array('', '', '', ''), $dom->saveXML($dom->documentElement)));
    }

你可以像这样使用它 stripAnchorTags($html);

如果你想让它忽略雅虎链接,那么就这样称呼它 stripAnchorTags($html, "yahoo");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 2014-02-24
    • 2015-02-04
    • 1970-01-01
    • 2014-11-12
    相关资源
    最近更新 更多