确保所有链接都有 target="_blank" 的正则表达式

Regular expression to ensure all links have target="_blank"

我有一个使用 CKEditor 生成的文本区域 HTML。我想确保用户输入的所有链接都有它们的 target="_blank"。我想我需要做两个正则表达式检查:一个是将任何 target="..." 替换为 target="_blank",另一个是在目标属性不存在的地方插入目标属性。我没有取得太大进步:

// where target attribute doesn't exist, add it
preg_replace("/<a(\s*(?!target)([\w\-])+=([\"\'])[^\"\']+)*\s*\/?>/", "<a target="_blank">", $input_lines);

这适用于这种简单的情况:

<a href="#">one</a> ---> <a target="_blank" href="#">one</a>

它不适用于 <a href="#" alt="hello">one</a>,我不确定为什么,但我通常不会用正则表达式做这种具有挑战性的事情。

此外,我如何将现有的 target="..."(例如 target="_parent")严格替换为 target="_blank"?

方法略有不同。

首先删除所有 target="..." 项。也许将 \btarget="[^"]*" 替换为空或单个 space.

接下来添加想要的 target="_blank" 项。也许将 <a 替换为 <a target="_blank".

但要注意这些在文件中意想不到的地方替换文本。正如对该问题的评论所说,使用适当的 HTML/XML 解析器几乎总是更好。

您可以安全地使用 PHP DOM 和 XPATH 来设置属性或修改所有 <a> 标签中的现有属性,如下所示:

$html = <<<DATA
<a href="somelink.html" target="_blank"><img src="myimage.jpg" alt="alt" title="sometitle" /></a>
<a href="somelink1.php" target="_parent">link_no1</a>
<a href="somelink2.php">link_no2</a>
<a href="someimage.jpg"><img src="image2.png"></a>
DATA;

$dom = new DOMDocument('1.0', 'UTF-8');
$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

$xpath = new DOMXPath($dom);
$links = $xpath->query('//a');

foreach($links as $link) { 
   $link->setAttribute('target', '_blank');
}

echo $dom->saveHTML();

IDEONE demo

输出:

<a href="somelink.html" target="_blank"><img src="myimage.jpg" alt="alt" title="sometitle"><a href="somelink1.php" target="_blank">link_no1</a><a href="somelink2.php" target="_blank">link_no2</a><a href="someimage.jpg" target="_blank"><img src="image2.png"></a></a>