即使没有协议,也可以将URL从文本转换为链接


Convert urls from text to links even if no protocol

假设$content是文本区域的内容

/*Convert the http/https to link */
     $content = preg_replace('!((https://|http://)+[a-z0-9_./?=&-]+)!i', '<a target="_blank" href="$1">$1</a> ', nl2br($_POST['helpcontent'])." ");
/*Convert the www. to link prepending http://*/
     $content = preg_replace('!((www'.)+[a-z0-9_./?=&-]+)!i', '<a target="_blank" href="http://$1">$1</a> ', $content." ");

这对链接来说还可以,但意识到当图像在文本中时会破坏标记。。。

我现在正在这样尝试:

$content = preg_replace('!'s((https?://|http://)+[a-z0-9_./?=&-]+)!i', ' <a href="$1">$1</a> ', nl2br($_POST['content'])." ");
$content = preg_replace('!((www'.)+[a-z0-9_./?=&-]+)!i', '<a target="_blank" href="http://$1">$1</a> ', $content." ");

图像是受尊重的,但问题是,使用http://或https://格式的url现在不会被转换。:

google.com->未转换(如预期)

www.google.com->转换良好的

http://google.com->未转换(意外)

https://google.com->未转换(意外)

我错过了什么?

-编辑-

目前几乎可以工作的解决方案:

$content = preg_replace('!('s|^)((https?://)+[a-z0-9_./?=&-]+)!i', ' <a href="$2" target="_blank">$2</a> ', nl2br($_POST['content'])." ");
$content = preg_replace('!('s|^)((www'.)+[a-z0-9_./?=&-]+)!i', '<a target="_blank" href="http://$2"  target="_blank">$2</a> ', $content." ");

这里的问题是,如果这是输入:

www.funcook.comhttp://www.funcook.comhttps://www.funcook.comfuncook.comhttp://funcook.comhttps://funcook.com

我想要的所有url(除了name.domain之外的所有url)都按预期进行了转换,但这是输出

www.funcook.comhttp://www.funcook.comhttps://www.funcook.com;funcook.comhttp://funcook.comhttps://funcook.com

注:;插入,知道为什么吗?

试试这个:

preg_replace('!('s|^)((https?://|www'.)+[a-z0-9_./?=&-]+)!i', ' <a href="$2">$2</a> ',$text);

它将获取以http://或www.开头的链接

示例

你不能100%。因为可能存在诸如stackoverflow.com之类的不具有www.的链路。

如果你只针对这些链接:

!(www'.'S+)!i

对你来说应该足够好。


编辑:至于你最新的问题,为什么http链接不会被转换,而https会被转换,你的第一个模式只搜索https://http://.,但事实并非如此。通过替换简化:

(https://|http://'.)

(https?://)

这将使s成为可选。

添加超链接的另一种方法是,您可以获取要解析的链接文本,并将其分解为数组。然后使用foreach(非常快速的函数-http://www.phpbench.com/)并将任何以http://、https://或www.开头或以.com/.org/等结尾的内容更改为链接。

我想也许是这样的:

$userTextArray = explode(" ",$userText);
foreach( $userTextArray as &$word){
    //if statements to test if if it starts with www. or ends with .com or whatever else
    //change $word so that it is a link
}

您的更改将反映在数组中,因为foreach语句中$userText之前有"&"。现在,只要将数组内爆回字符串,就可以开始了。

这在我的脑海中是有道理的。。。但我不能100%确定这就是你想要的

我也遇到过类似的问题。这是帮助我的功能。也许它会适合你的需求:

function clHost($Address) { 
   $parseUrl = parse_url(trim($Address)); 
   return  str_replace ("www.","",trim(trim($parseUrl[host] ? $parseUrl[host].$parseUrl[path] :  $parseUrl[path]),'/'));
}

此函数将返回没有协议的域和"www",因此您可以稍后自己添加它们。

例如:

$url = "http://www.". clHost($link);

我这样做是因为我找不到好的正则表达式。

's((https?://|www.)+[a-z0-9_./?=&-]+)

问题是你的首发迫使比赛以空位开始,所以,如果你没有空位,你的比赛就会失败。reg exp很好(没有''s),但为了避免替换图像,您需要添加一些内容来避免与它们匹配。

如果图像是纯html,请使用以下内容:(?<!src=")((https?://|www.)+[a-z0-9_./?=&-]+)

这将在url之前查找src=",以忽略它。

如果你使用另一个标记,告诉我,我会设法找到另一种方法来避免这些图像。