Рассмотрим по порядку предложенные регулярные выражения в этой теме:
#\<a.*?href=(?>[\"'])?([^\s\>'\"]+)(?>[\"'])?.*>#i
\<a - бэкслеш перед знаком '<' не нужен
<a.*?href - означает, что после строки
<a могут идти произвольные символы, исключая перевод строки (т.к. нет модификатора s), за которыми идет строка
href. Пример:
<a тра-ля-ля>ля-ляhref. Уже что-то не то?
href= - буквально означает эту строку. Но в HTML-е между
href и символом
= может быть любое количество пробельных символов, которые в регулярных выражениях имеют обозначение
\s. Так что вот такая строчка не выловится:
<a href = "тра-ля-ля">.
(?>[\"'])?.*> - а вот это вообще лишнее. Это регулярное выражение совпадет со строкой, в начале которой может быть одиночная или двойная кавычка, за которой идет строка любой длины (в том числе и нулевой), состоящая из
любых символов, исключая перевод строки (т.к. нет модификатора \s), за которой следует символ '>'. Проблема тут в том, что
любые символы могут включать символ '>'. Это означает, что данное регулярное выражение совпадет со строкой:
тра-ля-ля>ляля<<<<>>>>, что не совсем соответствует ожиданиям автора, составлявшего данное регулярное выражение.
Еще данное регулярное выражение некорректно выловит адреса, содержащие кавычки, знак '>' или пробельные символы. Например:
<a href="тра'ля"> <a href='тра"ля'> <a href="javascript: if ( 1 > 2) alert('hello') ">
"~<a(.+?)href[\s\r\n]*=[\s\r\n]*(((['\"])([^\\4>]*?)\\4)|([^\s\n\r>]*))[^>]*>[^<]*</a>~si"
Это вообще какой-то монстр. Попытаюсь в нем разобраться.
<a(.+?)href - та же проблема, что и в первом реге, т.е. оно совпадет со строкой
<a name="тра-ля">тра-ляhref.
[\s\r\n] - Тут лишние
\r\n, которые входят в класс пробельных символов
\s.
(((['\"])([^\\4>]*?)\\4)|([^\s\n\r>]*)) - прям какое-то нагромождение скобок

. Зачем их столько?
[^\\4>] - этот "фокус" не пройдет. Наверное, автор ожидал, что это регулярное выражение означает символ, отличный от '>' и того, что заключено в четвертую скобку. Но на самом деле это регулярное выражение означает символ, отличный от chr(4) и '>'.
[^>]*>[^<]*</a> - это тоже лишнее, как и в предыдущем примере. Содержит аналогичную ошибку. Кроме того, из-за этого "мусора" регулярка не совпадет с тэгом <A>, в котором находится любой другой тэг. Например, <a href="тра-ля-ля"><b>ля-ля</b></a>
"(?:.*?)href=\s*(?:"|')?([^"'<>]+)(?:"|\')?(?:.*?)?\>(.+?)<\/a>"
(?:.*?) - не могу понять назначения этого регулярного выражения.
href= - после
href тоже могут быть пробельные символы.
(?:"|') - можно сделать и так, но лучше вот так:
['"] - говорят, так быстрее будет работать.
(?:"|\')?(?:.*?)?\>(.+?)<\/a> - это снова лишнее. Хотя, тут нет ошибок, допущенных в предыдущих примерах.
Кроме того, это регулярное выражение содержит много ненужных скобок, а также некорректно вылавливает ссылки, содержащие символы
["'<>].
Ну и напоследок приведу свой вариант регулярного выражения, вырезающего ссылки:
PHP:
preg_match_all('/\\shref\\s*=\\s*("[^"]+"|\'[^\']+\'|[^\'">][^>\\s]+)/i', $str, $matches);
print_r($matches);
Буду рад, если кто-нибудь придирется к нему
