2016-06-16 12 views
0

Im Moment habe ich die folgende regex Link-Text und eine URL in folgendem Format zu erfassen:Regex Linkify URLs

[Link](http://link.com)

\[(.+)]\(((https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,}))\)

Wenn ich einen anderen Ausdruck danach hinzufügen URLs Linkify, es vermasselt diejenigen im obigen Format.

Gibt es einen einzigen regulären Ausdruck für beide Fälle?

http://link.com -><a href="http://link.com" target="_blank">http://link.com</a>

[Link](http://link.com) -><a href="http://link.com" target="_blank">Link</a>

PHP:

$string = preg_replace('/\[(.+)]\(((https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,}))\)/', '<a href="$2" target="_blank">$1</a>', $string); 
+0

Obligatorisch [ „Sie können nicht HTML mit Regex analysieren“] (http: //stackoverflow.com/a/1732454/1270789) verknüpfen. –

+1

@ KenY-N die Frage erneut gelesen ... – HamZa

+0

@frosty Ich würde definitiv nicht versuchen, dies in einem Regex zu tun. – HamZa

Antwort

2

gibt es keine wirklichen Möglichkeiten, um eine URL in einer Zeichenfolge zu identifizieren, da kann die URL-Syntax sehr kompliziert sein (zu kompliziert, um klar zu sein). Mit anderen Worten, Sie müssen akzeptieren, dass etwas, das wie [...](...) aussieht, für einen Link steht, ohne zu überprüfen, ob der Inhalt zwischen ( und ) wirklich eine URL ist. (Sie können immer parse_url nach, aber beachten Sie, dass gültige URLs ausgeschlossen werden können).

Was Sie suchen ist:

$result = preg_replace('~\[([^]]*)]\([^)]*\)~', '<a href="$2" target="_blank">$1</a>', $str); 

// If you want to hunt lonely urls in your text, you can always search 
// after extracting text nodes with XPath and a naive pattern like this: 

$dom = new DOMDocument; 
$dom->loadHTML($result); 

$xp = new DOMXPath($dom); 
$textNodes = $xp->query('//text()'); 

foreach($textNodes as $textNode) { 
    $textNode->nodeValue = preg_replace('~[hw](?:(?<=\bh)ttps?://|(?<=\bw)ww\.)\S+~i', '<a href="$0" target="_blank">$0</a>~', $textNode->nodeValue); 
} 

$result = $dom->saveHTML(); 

Hinweis: für bessere Ergebnisse, wenn Sie unbedingt die URL überprüfen möchten, können Sie das gleiche Muster mit preg_replace_callback verwenden können, um das letzte Zeichen des Spiels entfernen, bis parse_url funktioniert und führt den Austausch durch, aber es wird nicht sehr performant sein.

+1

@ HamZa: Ich habe einen schlechten Weg, um es zu tun. –

+0

Mein Code arbeitete für [...] (...) obwohl ... was ich meinte war, dass das Machen der einsamen URL preg_replace endete, die diejenigen im [...] (...) Format zu brechen . Ich kann auch nicht funktionieren. – frosty

+0

@frosty: Ich habe meine Antwort bearbeitet. Sie müssen dieses letzte Muster jetzt nur auf Textknoten anwenden, nachdem Sie sie mit XPath extrahiert haben, um das Problem zu vermeiden. –

0

Vielleicht helfen Ihnen ein wenig:

/** 
* Linkify Function 
* @param $tweet 
* @return mixed 
*/ 
function linkify_tweet($tweet) 
{ 
//Convert urls to <a> links 
$tweet = preg_replace("/([\w]+\:\/\/[\w-?&;#~=\.\/\@]+[\w\/])/", "<a href=\"mailto:[email protected]?subject=WEB $1\">$1</a>", $tweet); 

//Convert hashtags to twitter searches in <a> links 
$tweet = preg_replace("/#([A-Za-z0-9\/\.]*)/", "<a href=\"#\">#$1</a>", $tweet); 

//Convert attags to twitter profiles in <a> links 
$tweet = preg_replace("/@([A-Za-z0-9\/\.]*)/", "<a href=\"mailto:[email protected]?subject=MSG @$1\" class=\"userlink\">@$1</a>", $tweet); 

return $tweet; 
} 
0

Ersten Deal mit Abschlag Syntax. Dann fangen Sie einfache Links, die nicht verarbeitet wurden - Sie können ähnliche Regexp verwenden, aber ohne Parathesis. Wenn Sie alles ersetzen möchten, die innerhalb Leerzeichen Grenzen wie eine URL aussieht (HTML nicht übereinstimmen), dann wird dies tun:

\s(https?:\/\/(?:www\.|(?!www))[^\s.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})