如何从文本输入向 URL 添加锚标记

IT技术 php javascript jquery html
2021-02-07 02:31:14

我希望能够在评论字段中获取用户输入的文本并检查 URL 类型表达式,如果存在,则在显示评论时添加一个锚标记(到 url)。

我在服务器端使用 PHP,在客户端使用 Javascript(使用 jQuery),所以我应该在 URL 显示之前等待检查 URL 吗?或者在插入数据库之前添加锚标记?

所以

<textarea id="comment">check out blahblah.com or www.thisthing.co.uk or http://checkthis.us/</textarea>  

变成

<div id="commentDisplay">check out <a href="blahblah.com">blahblah.com</a> or <a href="www.thisthing.co.uk">www.thisthing.co.uk</a> or <a href="http://checkthis.us/">http://checkthis.us/</a></div>
6个回答

首先,一个请求。在将数据写入数据库之前不要这样做。相反,在向最终用户显示数据之前执行此操作。这将减少所有混乱,并让您在未来拥有更大的灵活性。

网上找到的一个例子如下:

$text = preg_replace('@(https?://([-\w\.]+)+(:\d+)?(/([-\w/_\.]*(\?\S+)?)?)?)@', '<a href="$1">$1</a>', $text);

来自daringfireball.net 的更彻底的一个

/**
 * Replace links in text with html links
 *
 * @param  string $text
 * @return string
 */
function auto_link_text($text)
{
   $pattern  = '#\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))#';
   $callback = create_function('$matches', '
       $url       = array_shift($matches);
       $url_parts = parse_url($url);

       $text = parse_url($url, PHP_URL_HOST) . parse_url($url, PHP_URL_PATH);
       $text = preg_replace("/^www./", "", $text);

       $last = -(strlen(strrchr($text, "/"))) + 1;
       if ($last < 0) {
           $text = substr($text, 0, $last) . "&hellip;";
       }

       return sprintf(\'<a rel="nowfollow" href="%s">%s</a>\', $url, $text);
   ');

   return preg_replace_callback($pattern, $callback, $text);
}
第一个函数不适用于 URL 中的破折号,就像这个页面的 URL: stackoverflow.com/questions/1959062/... 一样
2021-03-20 02:31:14
这会起作用,尽管我担心可能会出现延迟(它会一次显示大量评论)
2021-03-28 02:31:14
这真的很整洁(第二个功能)
2021-04-07 02:31:14
@JonathanSampson 当我使用第二个函数时,只使用一个没有“http://”的域名,它将当前域名附加到开头。例如:如果我输入 www.google.com,它会显示为 www.mydomain.com/www.google.com
2021-04-07 02:31:14
试一试。我怀疑你会遇到任何明显的滞后。
2021-04-10 02:31:14

我改编了 Jonathan Sampson 的正则表达式选项,以便它对什么是域更加宽容(不需要 http(s) 来限定)。

function hyperlinksAnchored($text) {
    return preg_replace('@(http)?(s)?(://)?(([-\w]+\.)+([^\s]+)+[^,.\s])@', '<a href="http$2://$4">$1$2$3$4</a>', $text);
}

适用于这些 URL(并成功省略了尾随句点或逗号):

http://www.google.com/
https://www.google.com/.
www.google.com
www.google.com.
www.google.com/test
google.com
google.com,
google.com/test
123.com/test
www.123.com.au
ex-ample.com
http://ex-ample.com
http://ex-ample.com/test-url_chars.php?param1=val1.
http://ex-ample.com/test-url_chars?param1=value1&param2=val+with%20spaces

希望能帮助某人。

我一直在寻找适用于所有这些不同情况的答案,如您的示例所示。感谢您抽出宝贵时间与社区分享!很好!
2021-03-16 02:31:14
这当前也捕获数字,例如 399.99
2021-03-22 02:31:14
@user1846348 是正确的。它也不适用于像 httpfun.com 这样的域
2021-03-27 02:31:14
这应该进行调整,以便(http)?(s)?(://)?成为(https?://)?- 我很确定这会解决前面提到的问题。(还需要更新$1、$2等)
2021-03-29 02:31:14

这是我的代码,用于格式化文本中的所有链接,包括电子邮件、带有和不带有协议的 url。

public function formatLinksInText($text)
{
    //Catch all links with protocol      
    $reg = '/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,}(\/\S*)?/'; 
    $formatText = preg_replace($reg, '<a href="$0" style="font-weight: normal;" target="_blank" title="$0">$0</a>', $text);

    //Catch all links without protocol
    $reg2 = '/(?<=\s|\A)([0-9a-zA-Z\-\.]+\.[a-zA-Z0-9\/]{2,})(?=\s|$|\,|\.)/';
    $formatText = preg_replace($reg2, '<a href="//$0" style="font-weight: normal;" target="_blank" title="$0">$0</a>', $formatText);

    //Catch all emails
    $emailRegex = '/(\S+\@\S+\.\S+)\b/';
    $formatText = preg_replace($emailRegex, '<a href="mailto:$1" style="font-weight: normal;" target="_blank" title="$1">$1</a>', $formatText);
    $formatText = nl2br($formatText);
    return $formatText;
}

就个人而言,我会在显示之前用 JS 标记它,似乎比自己编辑用户的评论更专业和可持续。

精炼 Markd 的答案以避免链接小数、百分比、数字日期 (10.3.2001)、省略号和 IP 地址:

    function addLinks($text) {
    return preg_replace('@(http)?(s)?(://)?(([a-zA-Z])([-\w]+\.)+([^\s\.]+[^\s]*)+[^,.\s])@', '<a target="ref" href="http$2://$4">$1$2$3$4</a>', $text);
}

效劳于:

HTTP:// www.google.com /
https://开头www.google.com /。
www.google.com
www.google.com
www.google.com/test
google.com的
google.com的
google.com/test
www.123.com.au
ex-ample.com
的http:// ex-ample.com
HTTP:// ex-ample.com/ test-url_chars.php?param1=val1
HTTP:// ex-ample.com/test-url_chars?param1=value1¶m2=val+with%20spaces

为不工作:

123.com/test (数字域而不包含“www”),
继续努力吧民意按.. ......保持平均值(省略号)
从 379 万(百分比和小数)上升 3.8% 至 394 万
由 Andrew Brooke 编辑 - 07.08.2013 19:57 dd.mm.yyyy日期)
10.1.1.1 (IP 地址)