PHP / RegEx - конвертировать URL-адреса в ссылки путем обнаружения .com / .net / .org / .edu и т. Д.

Я знаю, что было много вопросов с просьбой помочь преобразовать URL-адреса в интерактивные ссылки в строках, но я не нашел именно то, что искал.

Я хочу иметь возможность сопоставить любой из следующих примеров и превратить их в интерактивные ссылки:

<code>http://www.domain.com
https://www.domain.net
http://subdomain.domain.org
www.domain.com/folder
subdomain.domain.net
subdomain.domain.edu/folder/subfolder
domain.net
domain.com/folder
</code>

Я не хочу совпадать с random.stuff.separated.with.periods.

РЕДАКТИРОВАТЬ: имейте в виду, что эти URL-адреса должны быть найдены в более крупных строках «обычного»; текст. Например, я хочу сопоставить «домен.нет» в & quot; Привет! Заходите, проверьте domain.net! & Quot ;.

Я думаю, что это может быть достигнуто с помощью регулярного выражения, которое может определить, содержит ли соответствующий URL-адрес .com, .net, .org или .edu, за которым следует косая черта или пробел. Кроме опечатки пользователя, я не могу представить ни одного другого случая, в котором действительный URL имел бы один из тех, за которыми следовало бы что-нибудь еще.

Я понимаю, что существует много действительных доменных расширений, но мне не нужно поддерживать их все. Я могу просто выбрать, что поддерживать с чем-то вроде (com | net | org | edu) в регулярном выражении. К сожалению, я недостаточно квалифицирован в области регулярных выражений, чтобы знать, как правильно это реализовать.

Я надеюсь, что кто-то может помочь мне найти регулярное выражение (для использования с preg_replace в PHP), которое может сопоставлять URL-адреса, основанные практически на любом тексте, связанном одной или несколькими точками и заканчивающемся одним из указанных расширений, за которым следует пробел ИЛИ содержащий одно из указанных расширений, за которым следует косая черта и, возможно, папки.

Я провел несколько поисков и до сих пор не нашел того, что искал. Если там уже есть пост, который отвечает на это, я прошу прощения.

Заранее спасибо.

--- РЕДАКТИРОВАТЬ 3 ---

После нескольких дней проб и ошибок и некоторой помощи от SO вот что работает:

<code>preg_replace_callback('#(\s|^)((https?://)?(\w|-)+(\.(\w+|-)*)+(?<=\.net|org|edu|com|cc|br|jp|dk|gs|de)(\:[0-9]+)?(?:/[^\s]*)?)(?=\s|\b)#is',
                create_function('$m', 'if (!preg_match("#^(https?://)#", $m[2]))
                return $m[1]."<a href=\"http://".$m[2]."\">".$m[2]."</a>"; else return $m[1]."<a href=\"".$m[2]."\">".$m[2]."</a>";'),
                $event_desc);
</code>

Это модифицированная версия приведенного ниже кода анубхавы, и до сих пор, кажется, она делает именно то, что я хочу. Спасибо!

 Maciej A. Czyzewski28 июл. 2013 г., 02:15

Ответы на вопрос(3)

'/(http(s)?:\/\/)?[\w\/\.]+(\.((com)|(edu)|(net)|(org)))[\w\/]*/'

вы захотите добавить поддержку дополнительных символов для «-», «& quot;», «& quot;?» И т. Д. В последней скобке.

'/(http(s)?:\/\/)?[\w\/\.]+(\.((com)|(edu)|(net)|(org)))[\w\/\?=&-;]*/'

Это будет поддерживать параметры и номера портов.

например: www.foo.ca:8888/test?param1=val1&param2=val2

 vertigoelectric14 апр. 2012 г., 01:50
Это работает почти идеально! Спасибо. Единственная проблема сейчас - это одна из проблем, которые у меня были с решением анубхавы. URL без «http: //»; в начале появляются как относительные ссылки. Конечно, я мог бы провести тест на наличие этого и добавить его, если это не так. Я думаю, что это будет делать. Я сообщу вам, если возникнут какие-либо проблемы. РЕДАКТИРОВАТЬ: Ах, только что нашел проблему. Регулярное выражение соответствует строке, заканчивающейся на .edue, когда это не должно. Как я могу изменить регулярное выражение, чтобы после него сразу за расширением следовал пробел или косая черта?
 11 апр. 2012 г., 22:46
Тогда попробуйте & / apos; / (http (s)?: \ / \ /)? [\ W \ / \.] + (\. ((Com) | (edu) | (net) | (org))) [\ ж \ / \ = & амп; -;?] * / & APOS;
 16 апр. 2012 г., 17:08
& APOS; / (HTTP (s): \ / \ /?) [\ Ш \ / \.] + (\ ((Ком) | (Edu) | (нетто) | (орг)).) [^ \ Ш? .] {1} [\ ш \ / \ = & амп; -;?] * / & APOS; должен заблокировать "edue". Для последнего персонажа, вы можете просто проверить это, я думаю.
 vertigoelectric11 апр. 2012 г., 20:50
Спасибо за помощь. Я попробовал ваш второй пример и получил предупреждение PHP о неизвестном модификаторе & quot;? & Quot; в preg_replace
 vertigoelectric14 апр. 2012 г., 03:03
Я пошел с preg_replace_callback (), чтобы включить функцию, которая добавила & quot; http: // & quot; на ссылки, которые пропустили это. Теперь мне просто нужна некоторая помощь с вашим регулярным выражением в отношении сопоставления URL-адресов с этими расширениями ТОЛЬКО, если за расширениями следует пробел или косая черта (чтобы предотвратить сопоставление таких вещей, как & quot; .Com & quot; в Hello.Come, посетите oursite.com ! & quot; & lt; - Упс. Я только что понял, что если URL находится в конце предложения, за ним может следовать пунктуация. Может быть хитрее, чем я думал. Любые идеи? Возможно, он может соответствовать расширению с пробелом или любое не письмо.
Решение Вопроса

#(\s|^)((?:https?://)?\w+(?:\.\w+)+(?<=\.(net|org|edu|com))(?:/[^\s]*|))(?=\s|\b)#is

Code:

$arr = array(
'http://www.domain.com/?foo=bar',
'http://www.that"sallfolks.com',
'This is really cool site: https://www.domain.net/ isn\'t it?',
'http://subdomain.domain.org',
'www.domain.com/folder',
'Hello! You can visit vertigofx.com/mysite/rocks for some awesome pictures, or just go to vertigofx.com by itself',
'subdomain.domain.net',
'subdomain.domain.edu/folder/subfolder',
'Hello! Check out my site at domain.net!',
'welcome.to.computers',
'Hello.Come visit oursite.com!',
'foo.bar',
'domain.com/folder',

);
foreach($arr as $url) {   
   $link = preg_replace_callback('#(\s|^)((?:https?://)?\w+(?:\.\w+)+(?<=\.(net|org|edu|com))(?:/[^\s]*|))(?=\s|\b)#is',
           create_function('$m', 'if (!preg_match("#^(https?://)#", $m[2]))
               return $m[1]."<a href=\"http://".$m[2]."\">".$m[2]."</a>"; else return $m[1]."<a href=\"".$m[2]."\">".$m[2]."</a>";'),
           $url);
   echo $link . "\n";

OUTPUT:

<a href="http://www.domain.com/?foo=bar">http://www.domain.com/?foo=bar</a>
http://www.that"sallfolks.com
This is really cool site: <a href="https://www.domain.net">https://www.domain.net</a>/ isn't it?
<a href="http://subdomain.domain.org">http://subdomain.domain.org</a>
<a href="http://www.domain.com/folder">www.domain.com/folder</a>
Hello! You can visit <a href="http://vertigofx.com/mysite/rocks">vertigofx.com/mysite/rocks</a> for some awesome pictures, or just go to <a href="http://vertigofx.com">vertigofx.com</a> by itself
<a href="http://subdomain.domain.net">subdomain.domain.net</a>
<a href="http://subdomain.domain.edu/folder/subfolder">subdomain.domain.edu/folder/subfolder</a>
Hello! Check out my site at <a href="http://domain.net">domain.net</a>!
welcome.to.computers
Hello.Come visit <a href="http://oursite.com">oursite.com</a>!
foo.bar
<a href="http://domain.com/folder">domain.com/folder</a>

PS: Это регулярное выражение поддерживает только схемы http и https в URL. Например: если вы хотите поддерживать ftp, вам нужно немного изменить регулярное выражение.

 14 апр. 2012 г., 14:18
Хорошо, я отредактировал свой ответ снова согласно вашим комментариям, пожалуйста, проверьте его сейчас.
 vertigoelectric11 апр. 2012 г., 20:48
Спасибо. К сожалению, это не обнаруживает URL-адреса вообще. Помните, что URL-адреса должны быть найдены в блоках обычного текста. Например, мне нужно совпадать с «доменом». в чем-то вроде & quot; Привет! Проверьте мой сайт на domain.net! & Quot;
 11 апр. 2012 г., 21:06
Из вашего рассматриваемого примера оказалось, что у вас есть только список URL. Во всяком случае теперь это ясно, я только что отредактировал пожалуйста, проверьте мой ответ сейчас
 vertigoelectric14 апр. 2012 г., 01:43
Благодарю. Ваше новое регулярное выражение гораздо ближе, за исключением двух проблем. URL-адреса без http: // преобразуются в относительные ссылки, поэтому, например, URL-адрес some.domain.net превратится в ссылку типаvertigofx.com/something.domain.net (при условии, что у меня была страница, размещенная на сайте www.vertigofx.com) вместо ее собственной абсолютной ссылки. Также, когда он сопоставлял URL с путем к папке, он включал некоторые другие вещи после него.
 vertigoelectric16 апр. 2012 г., 23:32
Я выяснил конфликтную проблему. Я использовал nl2br (), прежде чем делать preg_replace, поэтому были & lt; br & gt; теги в конце строк, которые обычно идут сразу после URL. Я исправил это, и ваше регулярное выражение работает лучше, но все еще не идеально. Если я наберу & quot; welcome.to.computers & quot; это соответствует & quot; welcome.to.com & quot; и не должно. Я понимаю, что маловероятно, что кто-то наберет правильную комбинацию точек и букв для создания ложного URL, но должен быть способ исправить это. Можете ли вы сделать так, чтобы ДОЛЖНО заканчиваться пробелом или косой чертой, чтобы соответствовать?

чтобы разрешить все домены (.ca, .co.uk), а не только указанные.

$html = preg_replace_callback('#(\s|^)((https?://)?(\w|-)+(\.[a-z]{2,3})+(\:[0-9]+)?(?:/[^\s]*)?)(?=\s|\b)#is',
    create_function('$m', 'if (!preg_match("#^(https?://)#", $m[2])) return $m[1]."<a href=\"http://".$m[2]."\" target=\"blank\">".$m[2]."</a>"; else return $m[1]."<a href=\"".$m[2]."\" target=\"blank\">".$m[2]."</a>";'),
    $url);
 vertigoelectric18 июл. 2012 г., 16:14
Я не так хорош с регулярными выражениями. Как вам удалось определить разницу между концом действительного доменного имени и концом / началом плохо набранных предложений? Например, разница между «subdomain.domain.ca» и "Здравствуйте. Здравствуйте. Можете ли вы прочитать это?"

Ваш ответ на вопрос