Регулярное выражение для обеспечения того, чтобы все ссылки имели цель="пустой"


У меня есть текстовая область, которая использует CKEditor для генерации HTML. Я хочу убедиться, что все ссылки, которые вводит пользователь, имеют свои target="_blank". Я подумал, что мне нужно будет выполнить две проверки регулярных выражений: одну для замены любого target="..." на target="_blank", а другую - просто вставить целевой атрибут там, где целевого атрибута не существует. Я не добиваюсь большого прогресса:

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

Это работает в этом простом случае:

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

Это не работает для <a href="#" alt="hello">one</a>, я не уверен, почему, но тогда я обычно не делаю таких сложных вещей с регулярными выражениями.

Кроме того, как бы я заменил существующий target="..." (например, target="_parent") на строго target="_blank"?

Author: Wiktor Stribiżew, 2015-06-04

2 answers

Вы можете безопасно использовать 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

Вывод:

<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>
 2
Author: Wiktor Stribiżew, 2015-06-04 15:50:39

Несколько иной подход.

Сначала удалите все элементы target="...". Возможно, замените \btarget="[^"]*" ничем или одним пробелом.

Затем добавьте нужные элементы target="_blank". Возможно, заменить <a на <a target="_blank".

Но остерегайтесь этих замен текста в неожиданных местах файла. Как говорится в комментариях к вопросу, почти всегда лучше использовать правильный синтаксический анализатор HTML/XML.

 0
Author: AdrianHHH, 2015-06-04 14:38:19