Выражение RegEx, чтобы найти ссылки href и добавить к ним NoFollow - PullRequest
3 голосов
/ 16 марта 2010

Я пытаюсь написать правило RegEx, чтобы найти все href HTML-ссылки на моей веб-странице и добавить к ним 'rel = "nofollow".

Однако у меня есть список URL-адресов, которые должны быть исключены (например, для ЛЮБЫХ внутренних ссылок (подстановочных знаков) (например, pokerdiy.com) - так что любая внутренняя ссылка, в которой есть мое доменное имя, исключается из этого. хотите также иметь возможность указывать точные URL-адреса в списке исключений - например, http://www.example.com/link.aspx)

Вот что у меня до сих пор не работает:

(] +) (href = "http: //.*? (?! (Pokerdiy)) [^>] +>)

Если вам нужна дополнительная справка / информация, вы можете ознакомиться с полной информацией и требованиями здесь (пропустите верхнюю часть, чтобы перейти к мясу): http://www.snapsis.com/Support/tabid/601/aff/9/aft/13117/afv/topic/afpgj/1/Default.aspx#14737

Ответы [ 3 ]

10 голосов
/ 15 июля 2010

Улучшение в регулярном выражении Джеймса:

(<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);
6 голосов
/ 25 мая 2010

Я разработал немного более надежную версию, которая может определять, есть ли в теге привязки «rel =», поэтому атрибуты не дублируются.

(<a\s*(?!.*\brel=)[^>]*)(href="https?://)((?!blog.bandit.co.nz)[^"]+)"([^>]*)>

Матчи

<a href="http://google.com">Google</a>
<a title="Google" href="http://google.com">Google</a>
<a target="_blank" href="http://google.com">Google</a>
<a href="http://google.com" title="Google" target="_blank">Google</a>

но не совпадает

<a rel="nofollow" href="http://google.com">Google</a>
<a href="http://google.com" rel="nofollow">Google</a>
<a href="http://google.com" rel="nofollow" title="Google" target="_blank">Google</a>
<a href="http://google.com" title="Google" target="_blank" rel="nofollow">Google</a>
<a href="http://google.com" title="Google" rel="nofollow" target="_blank">Google</a>
<a target="_blank" href="http://blog.bandit.co.nz">Bandit</a>

Заменить на

$1$2$3"$4 rel="nofollow">

Надеюсь, это кому-нибудь поможет!

Джеймс

2 голосов
/ 16 марта 2010
(<a href="https?://)((?:(?!\b(pokerdiy.com|www\.example\.com/link\.aspx)\b)[^"])+)"

будет соответствовать первой части любой ссылки, которая начинается с http:// или https:// и не содержит pokerdiy.com или www.example.com/link.aspx в любом месте атрибута href. Замените это на

\1\2" rel="nofollow"

Если rel="nofollow" уже присутствует, вы получите два из них. И, конечно же, относительные ссылки или другие протоколы, такие как ftp:// и т. Д., Вообще не будут совпадать.

Пояснение:

(?!\b(foo|bar)\b)[^"] соответствует любому символу, отличному от ", если только в текущем местоположении невозможно сопоставить foo или bar. \b s, чтобы убедиться, что мы случайно не включим rebar или foonly.

Весь этот конструкт повторяется ((?: ... )+), и все, что совпадает, сохраняется в обратной ссылке \2.

Поскольку следующий токен, который должен быть сопоставлен, - это ", все регулярное выражение не выполняется, если атрибут содержит foo или bar где-либо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...