2009-05-26 10 views
34

Ich habe diesen Text:Extract URLs von Text in PHP

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

Wie kann ich den Link in einer anderen Variable extrahieren?

Ich weiß, es sollte mit regulären Ausdruck vor allem preg_match() sein, aber ich weiß nicht wie?

+1

mögliches Duplikat von [URL aus Zeichenfolge extrahieren] (http://stackoverflow.com/questions/4390556/extract-url-from-string) –

+3

@ Michael Berkowski Wie es sein wird Duplikat der Benutzer fragte am 26. Mai '09 um 14:13 aber Link erwähnt von Ihnen gefragt, im Dezember 8 '10 um 17:44 Uhr. Vielleicht ist das Gegenteil der Fall. – gvgvgvijayan

Antwort

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

Dies ist eine einfache Möglichkeit, die für viele Fälle funktionieren würde, nicht alle. Alle Matches werden in $ Matches eingefügt. Beachten Sie, dass Links in Ankerelementen nicht abgedeckt werden (< a href = "" ...), aber das war auch nicht in Ihrem Beispiel.

+1

-1: Sie haben gerade eine XSS-Schwachstelle erstellt, da sie auch JavaScript: URLs extrahiert. –

+0

Es ist nicht angegeben, wofür er es verwenden würde, daher entschuldige ich mich nicht. Er wollte nur URLs in Variablen bringen. – runfalk

+2

@Michael: Das Finden von Javascript-URLs ist noch keine Schwachstelle; sie ohne Überprüfung zu benutzen ist. Manchmal sind Anwesenheit und Anzahl solcher URLs nützliche Informationen. Ich hätte ein anderes Trennzeichen gewählt. :) – fuxia

9

URLs haben eine ziemlich complex definition - Sie müssen entscheiden, was Sie zuerst erfassen möchten. Ein einfaches Beispiel der Erfassung irgendetwas mit http:// und https:// beginnen könnte:

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

Beachten Sie, dass dies sehr einfach ist und ungültigen URLs erfassen könnte. Ich würde empfehlen aufholen POSIX und PHP regular expressions für komplexere Dinge.

+0

Das funktioniert perfekt für mich. Vielen Dank! –

8

Wenn der Text, aus dem Sie die URLs extrahieren, vom Benutzer gesendet wird und Sie das Ergebnis als Links anzeigen, müssen Sie sehr, SEHR vorsichtig sein, um zu vermeiden XSS vulnerabilities, am prominentesten "javascript:" Protokoll-URLs, aber auch malformed URLs, die Ihre Regexp und/oder den angezeigten Browser dazu bringen könnten, sie als Javascript URLs auszuführen. Zumindest sollten Sie nur URLs akzeptieren, die mit "http", "https" oder "ftp" beginnen.

Es gibt auch eine blog entry von Jeff, wo er einige andere Probleme mit dem Extrahieren von URLs beschreibt.

43

Wahrscheinlich ist der sicherste Weg, Code-Snippets von WordPress zu verwenden. Laden Sie das neueste (derzeit 3.1.1) herunter und sehen Sie wp-includes/formatting.php. Es gibt eine Funktion namens make_clickable, die einfachen Text für param enthält und formatierten String zurückgibt. Sie können Codes zum Extrahieren von URLs abrufen. Es ist jedoch ziemlich komplex.

Diese Ein-Zeilen-Regex könnte hilfreich sein.

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

Aber diese regex kann immer noch nicht, einige fehlerhafte URLs entfernen (ex. http://google:ha.ckers.org).

Siehe auch: How to mimic StackOverflow Auto-Link Behavior

+3

Ich hatte mit der Wordpress formatation.php herumgespielt und make_clickable ist eine gute Idee, aber es landet in der Hälfte der Wordpress in Abhängigkeiten. –

+0

Gute, um sicherzustellen, dass die Terminal-Teil ist kein seltsames Zeichen – Miguel

+0

Dies identifiziert nicht URL ohne HTTP, wie 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

Ich habe versucht zu tun, wie Nobu sagte, Wordpress, aber zu viel Abhängigkeiten zu anderen Wordpress-Funktionen, die ich entschied sich stattdessen Nobu den regulären Ausdruck für preg_match_all() und verwandelte sie in eine zu verwenden, Funktion, mit preg_replace_callback(); eine Funktion, die jetzt alle Links in einem Text durch anklickbare Links ersetzt. Es verwendet anonymous functions, also benötigen Sie PHP 5.3 oder Sie können den Code neu schreiben, um stattdessen eine gewöhnliche Funktion zu verwenden.

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

Nur eine Anmerkung: Ich habe Ihre Antwort auf eine anonyme Funktion als Rückruf anstelle von verwenden mit 'create_function()'. –

5

Sie könnten das tun ..

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

Der Code, der für mich gearbeitet (vor allem, wenn Sie mehrere Links in Ihrem $ string haben) ist:

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

Hoffnung, dass auch andere hilft.

+0

Ich habe alle Antwort getestet, das ist nur einer wird die HTML-Registerkarte entfernen – hkguile

1

Sie könnten dies versuchen, um den Link zu finden und den Link zu überarbeiten (fügen Sie den href-Link hinzu).

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

} 

siehe hier: http://php.net/manual/en/function.preg-match.phpsocialnews

0

Diese Regex funktioniert für mich großartig und ich habe mit allen Arten von URL geprüft,

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

Geprüft mit vielen URLs können hier finden 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; 
    } 
}