从文本中移除锚点

10

我需要从一些文本中删除锚点标签,但似乎无法使用正则表达式完成。
只删除锚点标签,不删除其中的内容。
例如,<a href="http://www.google.com/" target="_blank">google</a> 将变成 google

7个回答

14

确切地说,用正则表达式无法正确完成此任务。

以下是使用DOM的示例:

$xml = new DOMDocument(); 
$xml->loadHTML($html); 

$links = $xml->getElementsByTagName('a');

//Loop through each <a> tags and replace them by their text content    
for ($i = $links->length - 1; $i >= 0; $i--) {
    $linkNode = $links->item($i);
    $lnkText = $linkNode->textContent;
    $newTxtNode = $xml->createTextNode($lnkText);
    $linkNode->parentNode->replaceChild($newTxtNode, $linkNode);
}

在对DOM进行更改时,倒序循环非常重要。


回答很好,但我该怎么使用它?对用法不是很清楚。我只需要echo出$newTxtNode吗?还是lnkText? - jcobhams
@VyrenMedia Op 问如何用链接文本内容替换链接,因此在此循环的末尾,您将获得一个没有链接的 DOMDocument 对象。您可以使用 $xml->saveHTML(); 获取整个 HTML 结果。$lnkText 包含当前链接文本作为字符串,并且您可能想修整它。 - Yann Milin
非常感谢您的回复@Yann-Milin。然而,我已经找到了一个正则表达式的解决方案来解决这个问题。 - jcobhams
请参见正则表达式,语句“无法使用正则表达式正确完成”似乎不是真的。 - LarS
我想说的是,任何正则表达式解决方案都不是一个好的解决方案。显然,你可以对HTML文本运行正则表达式查询,但这并不意味着你应该这样做 :) 关于这个主题的有趣阅读:这里这里 - Yann Milin

11

那么您可以尝试

preg_replace('/<\/?a[^>]*>/','',$Source);

我已经在线在rubular上试过了。


1
这是不正确的,因为它也会剥离以a开头的其它标签,比如article或address。 - LarS
也许有更好的正则表达式:preg_replace('/<\s/?\sa(?:\s|\s+[^>])>/', '', $vars['panes']); - LarS
@CSᵠ的答案更好,可以删除'a'标签中间的偶数文本。 - Sadee

6

这个问题已经有答案了,但我想加入我的解决方案。我喜欢这个方案比被接受的方案更简单明了。

$content = 
    preg_replace(array('"<a href(.*?)>"', '"</a>"'), array('',''), $content);

1
这很好而且简单,也可以使用 $content = preg_replace(array('"<a (.*?)>"', '"</a>"'), array('',''), $content);,以防“href”不是锚标签中的第一个属性。 - David Thomas
@DavidThomas 很棒的贡献! - user1491929

6
你正在寻找 strip_tags() 函数。
<?php

// outputs 'google'
echo strip_tags('<a href="http://www.google.com/" target="_blank">google</a>');

2
我需要保留其他标签,只需删除锚点。 - Lior
@Lior 哦,我明白了。strip_tags确实不会这样做。有一个用户贡献的注释中提供了一个实现方法,可能会对你有帮助:http://php.net/manual/en/function.strip-tags.php#100054 - Pekka
@Pekka 你可以传递一个第二个参数给 strip_tags() 函数,这个参数是一个包含“可允许标签”的字符串:http://php.net/manual/en/function.strip-tags.php。 - Jasper
@Jasper但这对此处没有帮助,是吗?他必须指定在$allowable_tags中存在的所有标签。 - Pekka
@Pekka 很不幸的是,您必须将某些标记列入黑名单,而无法将要移除的标记列为白名单。但是,如果您了解正在解析的内容类型,您可能可以将该黑名单缩小到一个小列表。 - Jasper

5

使用正则表达式:

preg_replace('/<a[^>]+>([^<]+)<\/a>/i','\1',$html);

该代码段使用正则表达式替换HTML中的超链接标签,并保留其文本内容。

1
如果锚点元素内有<img...>元素会怎么样? - ridgerunner

0

尝试一下:

$str = '<p>paragraph</p><a href="http://www.google.com/" target="_blank" title="<>">google -> foo</a><div>In the div</div>';
// first, extract anchor tag
preg_match("~<a .*?</a>~", $str, $match);
// then strip the HTML tags
echo strip_tags($match[0]),"\n";

输出:

google -> foo

0
大部分这里的正则表达式对我没有帮助。其中一些会删除锚点内的内容(这完全不是 OP 所要求的),而且并不是所有内容都会被删除,其中一些匹配以 a 开头的任何标签等。
这就是我为自己在工作中创建的内容。我们遇到了一个问题,将具有锚点标记(具有许多数据属性和其他属性)的 HTML 传递给 wkhtmltopdf 有时会导致 PDF 无法产生,因此我想删除那些标记,同时保留文本。
正则表达式:
/ < /?a([^>] *)?> / ig
在 PHP 中,您可以执行以下操作:
$text = "<a href='http://www.google.com/'>Google1</a><br>" .
        "<a>Google2</a><br>" .
        "<afaketag href='http://www.google.com'>Google2</afaketag><br>" .
        "<afaketag>Google4</afaketag><br>" . 
        "<a href='http://www.google.com'><img src='someimage.jpg'></a>";
echo preg_replace("/<\/?a( [^>]*)?>/i", "", $text);

输出:

Google1<br>Google2<br><afaketag href='http://www.google.com'>Google2</afaketag><br><afaketag>Google4</afaketag><br><img src='someimage.jpg'>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接