Недавно встала необходимость спарсить из HTML документа все ссылки, не содержащие в себе атрибут rel=nofollow и не закрытые в noindex.
Обычно, эти ссылки выглядят как то так:
<noindex><a href=»http://wwwexample.com» rel=»nofollow»>текст ссылки</a></noindex>
Задача, как может показаться тривиальная. И правда, отсечь можно простейшей регуляркой типа:
<noindex.*?/noindex>
Но вот nofollow заставил меня поломать голову.
Для начала я решил что простой регулярки типа
<a.*?nofollow.*?>.*?</a>
Но на практике оказалось, что такой вариант, жадно съедает все между <a и /а> (пока не доберется до nofollow), если встречает ссылку не содержащую nofollow.
Поискав на просторах интернета решение своей задачи, ни чего путного так и не нашел, пришлось немножко напрячь голову, чтобы придумать как сделать так, чтобы получить все ссылки, не содержащие этого атрибута.
И вот что получилось в итоге:
<[^nofollow]*href=\»([^\»]*)\»[^nofollow]*>.*?</a>
Такая регулярка собирает все ссылки, не содержащие упоминания nofollow.
Вот и все.
Надеюсь это поможет сэкономить кому нибудь лишние час-полчаса личного времени, вместо того, чтобы гуглить и/или сидеть в раздумьях 🙂
А чем вариант с функцией stripos плох?
думаю данная функция будет быстрее работать, чем регулярка…
Здравствуйте, SeoMaks!
Этот вариант можно использовать для проверки является ли ссылка ссылкой, после их загрузки. Это лишнее действие. Зачем делать дополнительную проверку, если эту проверку можно вставить в регулярку, которая собирает ссылки?
ступил 🙂
подумал, что noindex и nofollow элементы одной конструкции ******
Да… было бы куда проще, если бы конструкция их была бы одинаковая…
Регулярка мягко говоря не идеальная, в квадратных скобках вы задаёте символьный класс, а не подстроку, поэтому написав в шаблоне [^nofollow], вы отсекаете ссылки, а имени или значении атрибутов которых присутствуют данные символы. Таким образом, ваша регулярка отбросит даже ссылку вида link, поскольку в имени атрибута title присутствует буква из исключенного класса
M@x, спасибо за наводку!
Есть идеи, как сделать это иначе?