Извлечение URL из текста в PHP

У меня есть этот текст:

$string = "this is my friend's website http://example.com I think it is coll"; 

Как я могу извлечь ссылку в другую переменную?

Я знаю, что это должно быть с помощью регулярного выражения, особенно preg_match() но я не знаю, как это сделать?

Вероятно, самым безопасным способом является использование фрагментов кода из WordPress. Загрузите последнюю версию (в настоящее время 3.1.1) и посмотрите wp-includes / formatting.php. Существует функция с именем make_clickable, которая имеет простой текст для параметра и возвращает форматированную строку. Вы можете извлекать коды для извлечения URL-адресов. Это довольно сложно.

Это одно регулярное выражение может оказаться полезным.

 preg_match_all('#\bhttps?://[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/))#', $string, $match); 

Но это регулярное выражение по-прежнему не может удалить некоторые некорректные URL-адреса (например, http://google:ha.ckers.org ).

См. Также: Как имитировать поведение автоматической привязки StackOverflow

Я пытался сделать так, как сказал Нобу, используя WordPress, но для многих зависимостей от других функций WordPress я вместо этого предпочел использовать регулярное выражение Nobu для preg_match_all() и превратил его в функцию, используя preg_replace_callback() ; функция, которая теперь заменяет все ссылки в тексте с помощью интерактивных ссылок. Он использует анонимные функции, поэтому вам понадобится PHP 5.3 или вы можете переписать код для использования обычной функции.

 <?php /** * Make clickable links from URLs in text. */ function make_clickable($text) { $regex = '#\bhttps?://[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/))#'; return preg_replace_callback($regex, function ($matches) { return "<a href=\'{$matches[0]}\'>{$matches[0]}</a>"; }, $text); } 

URL-адреса имеют довольно сложное определение – вы должны решить, что вы хотите захватить первым. Простой пример, содержащий все, начиная с http:// и https:// может быть:

 preg_match_all('!https?://\S+!', $string, $matches); $all_urls = $matches[0]; 

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

Если текст, который вы извлекаете из URL-адресов, отправляется пользователю, и вы собираетесь отображать результат как ссылки в любом месте, вы должны быть очень осторожны, чтобы избежать уязвимостей XSS , наиболее значимых URL-адресов протокола «javascript:», а также искаженных URL-адреса, которые могут обмануть ваше регулярное выражение и / или отображение браузера в их выполнение как URL-адреса Javascript. По крайней мере, вы должны принимать только URL-адреса, начинающиеся с «http», «https» или «ftp».

Также есть запись в блоге Джеффа, где он описывает некоторые другие проблемы с извлечением URL-адресов.

Вы могли бы так поступить.

 <?php $string = "this is my friend's website http://example.com I think it is coll"; echo explode(' ',strstr($string,'http://'))[0]; //"prints" http://example.com 

Код, который работал для меня (особенно если у вас есть несколько ссылок в вашей строке $):

 $string = "this is my friend's website http://example.com I think it is cool, but this is cooler http://www.memelpower.com :)"; $regex = '/\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|$!:,.;]*[A-Z0-9+&@#\/%=~_|$]/i'; preg_match_all($regex, $string, $matches); $urls = $matches[0]; // go over all links foreach($urls as $url) { echo $url.'<br />'; } 

Надежда, которая помогает и другим.

 preg_match_all('/[az]+:\/\/\S+/', $string, $matches); 

Это простой способ, который бы работал во многих случаях, а не во всех. Все совпадения помещаются в $ match. Обратите внимание, что это не охватывает ссылки в элементах привязки (<a href = "" …), но это также не было в вашем примере.

 preg_match_all ("/a[\s]+[^>]*?href[\s]?=[\s\"\']+". "(.*?)[\"\']+.*?>"."([^<]+|.*?)?<\/a>/", $var, &$matches); $matches = $matches[1]; $list = array(); foreach($matches as $var) { print($var."<br>"); } 

Вы можете попробовать это, чтобы найти ссылку и пересмотреть ссылку (добавить ссылку href).

 $reg_exUrl = "/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/"; // The Text you want to filter for urls $text = "The text you want to filter goes here. http://note.taable.com"; if(preg_match($reg_exUrl, $text, $url)) { echo preg_replace($reg_exUrl, "<a href="{$url[0]}">{$url[0]}</a> ", $text); } else { echo "No url in the text"; } 

см. здесь: http://php.net/manual/en/function.preg-match.php socialnews

Это Regex отлично работает для меня, и я проверил все типы URL,

 <?php $string = "Thisregexfindurlhttp://www.rubular.com/r/bFHobduQ3n mixedwithstring"; preg_match_all('/(https?|ssh|ftp):\/\/[^\s"]+/', $string, $url); $all_url = $url[0]; // Returns Array Of all Found URL's $one_url = $url[0][0]; // Gives the First URL in Array of URL's ?> 

Проверено с большим количеством URL можно найти здесь http://www.rubular.com/r/bFHobduQ3n

 public function find_links($post_content){ $reg_exUrl = "/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/"; // Check if there is a url in the text if(preg_match_all($reg_exUrl, $post_content, $urls)) { // make the urls hyper links, foreach($urls[0] as $url){ $post_content = str_replace($url, '<a href="'.$url.'" rel="nofollow"> LINK </a>', $post_content); } //var_dump($post_content);die(); //uncomment to see result //return text with hyper links return $post_content; } else { // if no urls in the text just return the text return $post_content; } }