0

我想生成一个链接表单评论。

这里有两种类型的链接从评论生成。

$string = "Hello @username you need to check this http://github.com and @username you need to https://stackoverflow.com/questions/ask";

提到的用户名和链接并非每次都需要。

我得到了链接的解决方案。

$comment_with_link = preg_replace('/\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[A-Z0-9+&@#\/%=~_|]/i',"<a href=\"\\0\">\\0</a>",$string);

但现在我需要对@username 提出任何建议??

4

2 回答 2

0
$comment_with_link = preg_replace('/\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[A-Z0-9+&@#\/%=~_|]/i',"<a href=\"\\0\">\\0</a>",$string); //for links
$comment_with_link = preg_replace("/\b(@(\w+))/"," <a href='https://example.com/users/\1'>\0</a> ", $comment_with_link); //for users
$comment_with_link = preg_replace("/\b(#(\w+))/"," <a href='https://example.com/colleges/\1'>\0</a> ", $comment_with_link); //for colleges
//note: first replace link then the mention

样本输出

Helo @user1 from #college1, visit https://example.com   ----> Helo <a href="https://example.com/users/user1">@user1</a> from <a href="https://example.com/colleges/college1">#college1</a>, visit <a href="https://example.com">https://example.com</a>
于 2020-04-05T06:13:42.253 回答
0

如果用户名不是每次都出现,您可以将该部分设为可选,并使用 2 个捕获组和preg_replace_callback

在回调中检查组 1(用户名)的值是否不为空,并使用组值来组装链接的值。

(?<!\S)(?:(@[^\s@]+)(?!\S)[^h]*(?:h(?!ttp)[^h]*)*+)?\K((?:https?|ftp|file)://\S+)

解释

  • (?<!\S)断言左空白边界
  • (?:非捕获组
    • (@[^\s@]+)捕获组 1匹配用户名
    • (?!\S)断言右空白边界
    • [^h]*匹配 0 次以上的任何字符,除了h
    • (?:非捕获组
      • h(?!ttp)[^h]*h仅在不直接跟随时匹配ttp
    • )*+使用所有格量词关闭组并重复 0 次以上
  • )?关闭组并使其成为用户名的选项
  • \K忘记匹配的内容
  • (捕获组 2
    • (?:https?|ftp|file)匹配协议
    • ://\S+匹配://后跟 1+ 次非空白字符
  • )关闭组 2

正则表达式演示| php演示

$string = <<<STR
Hello @username you need to check this http://github.com
and @username you need to https://stackoverflow.com/questions/ask 
or https://stackoverflow.com
STR;

$pattern = "~(?<!\S)(?:(@[^\s@]+)(?!\S)[^h]*(?:h(?!ttp)[^h]*)*+)?\K((?:https?|ftp|file)://\S+)~";

$result = preg_replace_callback($pattern, function($m){
    return sprintf('<a href="%s">%s</a>', $m[2],$m[1] !== "" ?  $m[1] : $m[2]);
}, $string);

echo $result;

输出

Hello @username you need to check this <a href="http://github.com">@username</a>
and @username you need to <a href="https://stackoverflow.com/questions/ask">@username</a> 
or <a href="https://stackoverflow.com">https://stackoverflow.com</a>

笔记

@如果用户名和 url 之间不能出现,你可以使用[^h@]*而不是[^h]*

于 2020-04-05T08:40:29.687 回答