我目前有以下正则表达式以下列格式捕获链接文本和URL:
[Link](http://link.com)
\[(.+)]\(((https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,}))\)
当我之后添加另一个表达式来链接URL时,它会以上述格式混淆。
是否有单一的正则表达式来处理这两种情况?
http://link.com
- &gt; <a href="http://link.com" target="_blank">http://link.com</a>
[Link](http://link.com)
- &gt; <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 :(得分:2)
由于url语法可能非常复杂(太复杂而无法清除),因此没有真正的方法来识别字符串中的url。换句话说,您必须接受类似[...](...)
的内容代表链接,而不是尝试验证(
和)
之间的内容是否真的是一个网址。 (之后您可以随时使用parse_url
,但请注意,它可能会排除有效的网址。
您正在寻找的是:
$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();
注意:为了获得更好的结果,如果您绝对想要检查网址,可以使用与preg_replace_callback
相同的模式,删除匹配的最后一个字符,直到parse_url
工作并执行替换,但它不会非常高效。
答案 1 :(得分:0)
也许这对你有所帮助:
/**
* Linkify Function
* @param $tweet
* @return mixed
*/
function linkify_tweet($tweet)
{
//Convert urls to <a> links
$tweet = preg_replace("/([\w]+\:\/\/[\w-?&;#~=\.\/\@]+[\w\/])/", "<a href=\"mailto:w2m@bachecubano.com?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:w2m@bachecubano.com?subject=MSG @$1\" class=\"userlink\">@$1</a>", $tweet);
return $tweet;
}
答案 2 :(得分:0)
首先处理markdown语法。然后捕获未处理的纯链接 - 您可以使用类似的正则表达式,但没有parethesis。如果你想在空白限制内更换看起来像url的所有内容(html将不匹配),那么这样做:
\s(https?:\/\/(?:www\.|(?!www))[^\s.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})