Regex для анализа ссылок, содержащих определенные слова - PullRequest
1 голос
/ 01 февраля 2010

Принимая это продвинуться на шаг вперед, может кто-нибудь сказать мне, в чем разница между этими двумя регулярными выражениями? Кажется, они оба выполняют одно и то же: вытаскивают ссылку из html.

Выражение 1:

'/(https?://)?(www.)?([a-zA-Z0-9_%]*)\b.[a-z]{2,4}(.[a-z]{2})?((/[a-zA-Z0-9_%])+)?(.[a-z])?/'

Выражение 2:

'/<a.*?href\s*=\s*["\']([^"\']+)[^>]*>.*?<\/a>/si'

Какой из них лучше использовать? И как я могу изменить одно из этих выражений, чтобы оно соответствовало только ссылкам, содержащим определенные слова, и игнорировало совпадения, которые не содержат этих слов?

Спасибо.

Ответы [ 4 ]

3 голосов
/ 01 февраля 2010

Разница в том, что выражение 1 ищет действительные и полные URI, следуя спецификации. Таким образом, вы получаете все полные URL, которые находятся где-то внутри кода. На самом деле это не связано с получением всех ссылок, потому что он не соответствует относительным URL-адресам, которые очень часто используются, и он получает все URL-адреса, а не только те, которые являются целевыми ссылками.

Второй ищет теги a и получает содержимое атрибута href. Так что этот получит вам каждую ссылку. За исключением одной ошибки * в этом выражении, использовать ее вполне безопасно, и она будет работать достаточно хорошо, чтобы получить каждую ссылку - она ​​проверяет наличие достаточно различий, таких как пробелы или другие атрибуты.

* Однако в этом выражении есть одна ошибка, так как он не ищет закрывающую кавычку атрибута href, вы должны добавить это, или вы можете сопоставить странные вещи:

/<a.*?href\s*=\s*["\']([^"\'>]+)["\'][^>]*>.*?<\/a>/si

изменить в ответ на комментарий:

Чтобы найти word внутри ссылки, используйте:

/<a.*?href\s*=\s*["\']([^"\'>]*word[^"\'>]*)["\'][^>]*>.*?<\/a>/si

Чтобы найти word внутри текста ссылки, используйте:

/<a.*?href\s*=\s*["\']([^"\'>]+)["\'][^>]*>.*?word.*?<\/a>/si
1 голос
/ 01 февраля 2010
/<a.*?href\s*=\s*["']([^"']+)[^>]*>.*?<\/a>/si

Вы должны быть очень осторожны с .*, даже в не жадной форме. . легко соответствует больше, чем вы рассчитывали, особенно в режиме dotall. Например:

<a name="foo">anchor</a>
<a href="...">...</a>

Совпадает с начала первого <a до конца второго.

Не говоря уже о таких случаях, как:

<a href="a"></a >
<a href="b"></a>

или

<a href="a'b>c">

или

<a data-href="a" title="b>c" href="realhref">

или

<!-- <a href="notreallyalink"> -->

и еще много других интересных случаев. Вы можете попытаться уточнить свое регулярное выражение, чтобы использовать больше возможностей, но вы никогда не получите их все, потому что HTML не может быть проанализирован с помощью регулярного выражения (расскажите своим друзьям)!

HTML + regex - игра для дураков. Сделай себе одолжение. Используйте анализатор HTML.

1 голос
/ 01 февраля 2010

В большинстве случаев я настоятельно рекомендую использовать парсер HTML (например, this ) для получения этих ссылок. Использование регулярных выражений для разбора HTML будет проблематичным, поскольку HTML не является регулярным, и у вас не будет конца крайним случаям, которые стоит рассмотреть.

См. здесь для получения дополнительной информации.

0 голосов
/ 01 февраля 2010

Вкратце первый - мусор, но, похоже, он пытается сопоставить ссылку как текст, второй - элемент html.

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