Улучшение в регулярном выражении Джеймса:
(<a\s*(?!.*\brel=)[^>]*)(href="https?://)((?!(?:(?:www\.)?'.implode('|(?:www\.)?', $follow_list).'))[^"]+)"((?!.*\brel=)[^>]*)(?:[^>]*)>
Это регулярное выражение будет соответствовать ссылкам НЕ в строковом массиве $ follow_list. Строки не нуждаются в ведущем «www». :)
Преимущество состоит в том, что это регулярное выражение сохранит другие аргументы в теге (например, цель, стиль, заголовок ...). Если аргумент rel
уже существует в теге, регулярное выражение НЕ будет совпадать, поэтому вы можете принудительно следить за URL-адресами, не входящими в $ follow_list
Заменить на:
$1$2$3"$4 rel="nofollow">
Полный пример (PHP):
function dont_follow_links( $html ) {
// follow these websites only!
$follow_list = array(
'google.com',
'mypage.com',
'otherpage.com',
);
return preg_replace(
'%(<a\s*(?!.*\brel=)[^>]*)(href="https?://)((?!(?:(?:www\.)?'.implode('|(?:www\.)?', $follow_list).'))[^"]+)"((?!.*\brel=)[^>]*)(?:[^>]*)>%',
'$1$2$3"$4 rel="nofollow">',
$html);
}
Если вы хотите перезаписать rel
несмотря ни на что, я бы использовал preg_replace_callback
подход, при котором в обратном вызове атрибут rel заменяется отдельно:
$subject = preg_replace_callback('%(<a\s*[^>]*href="https?://(?:(?!(?:(?:www\.)?'.implode('|(?:www\.)?', $follow_list).'))[^"]+)"[^>]*)>%', function($m) {
return preg_replace('%\srel\s*=\s*(["\'])(?:(?!\1).)*\1(\s|$)%', ' ', $m[1]).' rel="nofollow">';
}, $subject);