2009-05-26 6 views
34

У меня есть этот текст:Извлечение ссылок из текста в PHP

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

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

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

+1

Возможный дубликат [Извлечь URL из string] (http://stackoverflow.com/questions/4390556/extract-url-from-string) –

+3

@ Michael Berkowski, как он будет дублировать пользователя, которого вы указали 26 мая 2009 года в 14:13, но ссылка, упомянутая вами, 8 декабря в 17:44. Возможно, наоборот. – gvgvgvijayan

ответ

3
preg_match_all('/[a-z]+:\/\/\S+/', $string, $matches); 

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

+1

-1: вы только что создали уязвимость XSS, так как она также будет извлекать javascript: URL. –

+0

Не указано, для чего он его использовал, поэтому я не учитываю это. Он просто хотел получить URL-адреса в переменных. – runfalk

+2

@Michael: Поиск URL-адресов JavaScript еще не является уязвимостью; используя их без какой-либо проверки. Иногда присутствие и количество таких URL-адресов являются полезной информацией. Я бы выбрал другой разделитель. :) – fuxia

9

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

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

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

+0

Это прекрасно работает для меня. Благодаря! –

8

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

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

43

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

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

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

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

Смотрите также: How to mimic StackOverflow Auto-Link Behavior

+3

У меня была игра с Wordpress formatting.php и использование make_clickable - хорошая идея, но в итоге она всасывает половину wordpress в зависимостях. –

+0

Хорошо, чтобы убедиться, что терминальная часть не является странным символом. – Miguel

+0

Это не идентифицирует URL-адрес без http, например google.com. –

2
preg_match_all ("/a[\s]+[^>]*?href[\s]?=[\s\"\']+". 
       "(.*?)[\"\']+.*?>"."([^<]+|.*?)?<\/a>/", 
       $var, &$matches); 

$matches = $matches[1]; 
$list = array(); 

foreach($matches as $var) 
{  
    print($var."<br>"); 
} 
13

я пытался сделать, как сказал Ноб, используя Wordpress, но гораздо зависимостей других функций WordPress я вместо этого решил использовать регулярные выражения Ноба для preg_match_all() и превратил его в функция, используя preg_replace_callback(); функция, которая теперь заменяет все ссылки в тексте с помощью интерактивных ссылок. Он использует anonymous functions, поэтому вам понадобится 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); 
} 
+2

Просто примечание. Я обновил ваш ответ, чтобы использовать анонимную функцию в качестве обратного вызова вместо используя 'create_function()'. –

5

Вы могли бы сделать вот так ..

<?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 
5

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

$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 />'; 
} 

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

+0

Я протестировал все ответы, это только один удалит вкладку html – hkguile

1

Вы можете попробовать эту ссылку, чтобы найти ссылку и перейдите по ссылке (добавьте ссылку 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.phpsocialnews

0

Это 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

0
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; 
    } 
}