Using this regex, I can find all usernames within the body of my comments and change them into hyperlinks:
$body = preg_replace('/\B\@([a-zA-Z0-9_]{1,20})/', '<a href="/profiles/$1">$0</a>', $row["commentBody"]);
This will convert @user
to <a href="/profiles/user">@user</a>
(broken link obviously).
However it will also convert h@user
to h<a href="/profiles/user">@user</a>
which I don't want.
How can I modify the regex to only change the string if their is two spaces either side of it? Thanks.
EDIT missed the two spaces thing before and fixed to limit to 16 characters:
$body = preg_replace('/(?<=^| )\@([a-zA-Z0-9_]{1,16})(?: )/', '<a href="/profiles/$1">$0</a>', $row["commentBody"]);
(end edit)
Better is this:
$body = preg_replace('/(?<=^|\s|[([])\@([a-zA-Z0-9_]{1,20})/', '<a href="/profiles/$1">$0</a>', $row["commentBody"]);
I suspect the current problem is that you have a hidden character or something in there. For example, look what happens if you do this:
$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);
You aren't feeding it h@user
, even though it looks like it, which explains why you are getting the output you are describing.
Also, you say it will convert $user
. It shouldn't; the way you have it written, it will match @user
, but not $user
. If you want it to match both, replace \@
with [@$]
.
preg_replace('/(?:^|(?<=\s))\@(\w{1,20})(?!\w)/', '<a href="/profiles/$1">$0</a>', ...
or
preg_replace('/(?:^|(?<=\s))\@(\w{1,20})(?=\s|$)/', ...