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

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

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

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 

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

EDIT: Пожалуйста, имейте в виду, что эти URL-адреса должны быть найдены в больших строках «нормального» текста. Например, я хочу сопоставить «domain.net» в «Hello! Come, проверьте домен.com!».

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

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

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

Я сделал несколько поисков и до сих пор не нашел то, что искал. Если уже существует сообщение SO, которое отвечает на это, я извиняюсь.

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

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

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

 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); 

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

Вы можете использовать это регулярное выражение:

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

Код:

 $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"; 

ВЫВОД:

 <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, тогда вам нужно немного изменить регулярное выражение.

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

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

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

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

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

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

 $html = preg_replace_callback('#(\s|^)((https?://)?(\w|-)+(\.[az]{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);