wake-up-neo.com

Extrahieren Sie URLs aus Text in PHP

Ich habe diesen Text:

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

Wie kann ich den Link in eine andere Variable extrahieren?

Ich weiß, dass es sein sollte, wenn man reguläre Ausdrücke verwendet, insbesondere preg_match(), aber ich weiß nicht wie?

38
ahmed

Der sicherste Weg ist wahrscheinlich die Verwendung von Code-Snippets von WordPress. Laden Sie die neueste Version (derzeit 3.1.1) herunter und sehen Sie unter wp-includes/formatting.php nach. Es gibt eine Funktion namens make_clickable, die Klartext für param enthält und formatierte Zeichenfolge zurückgibt. Sie können Codes zum Extrahieren von URLs verwenden. Es ist ziemlich komplex.

Diese einzeilige Regex kann hilfreich sein.

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

Dieser reguläre Ausdruck kann jedoch einige fehlerhafte URLs (z. B. http://google:ha.ckers.org) nicht entfernen.

Siehe auch: So stellen Sie das StackOverflow Auto-Link-Verhalten nach

45
Nobu

Ich habe versucht, das zu tun, was Nobu mit Wordpress gesagt hat, aber zu vielen Abhängigkeiten zu anderen WordPress-Funktionen entschied ich mich stattdessen, Nobus regulären Ausdruck für preg_match_all() zu verwenden, und wandelte ihn in eine Funktion um, wobei preg_replace_callback() ; eine Funktion, die jetzt alle Links in einem Text durch anklickbare Links ersetzt. Es verwendet anonyme Funktionen , so dass Sie PHP 5.3 benötigen, oder Sie können den Code umschreiben, 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);
}
15
Mikael Roos

URLs haben ein ziemlich komplexe Definition - Sie müssen zuerst entscheiden, was Sie erfassen möchten. Ein einfaches Beispiel, bei dem alles aufgenommen wird, das mit http:// und https:// beginnt, könnte folgendermaßen aussehen:

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

Beachten Sie, dass dies sehr einfach ist und ungültige URLs erfassen kann. Ich würde empfehlen, POSIX und PHP reguläre Ausdrücke für komplexere Dinge einzuholen.

10
soulmerge

Wenn der Text, aus dem Sie die URLs extrahieren, vom Benutzer übermittelt wird und Sie das Ergebnis an beliebiger Stelle als Links anzeigen, müssen Sie sehr vorsichtig sein, um XSS-Schwachstellen zu vermeiden , aber auch fehlerhafte URLs , die Ihren regulären Ausdruck und/oder den angezeigten Browser dazu verleiten könnten, sie als Javascript-URLs auszuführen. Zumindest sollten Sie nur URLs akzeptieren, die mit "http", "https" oder "ftp" beginnen.

Es gibt auch einen Blogeintrag von Jeff, in dem er einige andere Probleme beim Extrahieren von URLs beschreibt.

8

Der Code, der für mich funktioniert hat (insbesondere wenn Sie mehrere Links in Ihrem $ string haben), lautet: 

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

Hoffe, das hilft auch anderen.

5
Kai Noack

Das könnte man so machen ..

<?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
preg_match_all('/[a-z]+:\/\/\S+/', $string, $matches);

Dies ist ein einfacher Weg, der in vielen Fällen und nicht in allen Fällen funktionieren würde. Alle Spiele werden in $ -Matches gesetzt. Beachten Sie, dass dies keine Links in Ankerelementen (<a href = "" ...) abdeckt, dies war jedoch nicht in Ihrem Beispiel.

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

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

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

Sie können 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://example.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/de/function.preg-match.php

1
HTML5 developer
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; 
    }
}
0
karolkarp

Dieses Regex funktioniert super für mich und ich habe mit allen Arten von URLs überprü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
?>

Mit vielen URLs überprüft, finden Sie hier http://www.rubular.com/r/bFHobduQ3n

0