正则表达式将文本中的用户名转换为其个人资料的链接

时间:2013-11-16 16:37:43

标签: php regex

使用这个正则表达式,我可以在我的评论正文中找到所有用户名,并将它们更改为超链接:

$body = preg_replace('/\B\@([a-zA-Z0-9_]{1,20})/', '<a href="/profiles/$1">$0</a>', $row["commentBody"]);

这会将@user转换为<a href="/profiles/user">@user</a>(显然会断开链接)。

然而,它也会将h@user转换为我不想要的h<a href="/profiles/user">@user</a>

我如何修改正则表达式只改变字符串,如果它们两边都是两个空格?感谢。

2 个答案:

答案 0 :(得分:1)

preg_replace('/(?:^|(?<=\s))\@(\w{1,20})(?!\w)/', '<a href="/profiles/$1">$0</a>', ...

preg_replace('/(?:^|(?<=\s))\@(\w{1,20})(?=\s|$)/', ...

答案 1 :(得分:0)

编辑错过了之前的两个空格并固定为限制为16个字符:

$body = preg_replace('/(?<=^|  )\@([a-zA-Z0-9_]{1,16})(?:  )/', '<a href="/profiles/$1">$0</a>', $row["commentBody"]);

(结束编辑)

更好的是:

$body = preg_replace('/(?<=^|\s|[([])\@([a-zA-Z0-9_]{1,20})/', '<a href="/profiles/$1">$0</a>', $row["commentBody"]);

我怀疑当前的问题是你有一个隐藏的角色或其他东西。例如,看看如果你这样做会发生什么:

$body = 'h<!-- comment -->@user'; // or even something like '<strong>h</strong>@user'
$body = preg_replace('/\B\@([a-zA-Z0-9_]{1,20})/', '<a href="/profiles/$1">$0</a>', $body);
echo htmlentities($body);

你没有喂它h@user,即使它看起来像这样,这也解释了为什么你得到你正在描述的输出。

另外,你说它会转换$user。它不应该;你写它的方式,它将匹配@user,但不匹配$user。如果您希望它与两者匹配,请将\@替换为[@$]