preg_replace具有相似的值

I am working on a mentions system and I have run across a problem, when I am looping through and changing the mentions to links, it will replace similar ones such as @tom and @tom123 with the same link to /tom/ instead of individual.

I have tried using regex and preg_replace however I am also checking to see if the username actually exists, so I am just wondering if there is a way I can prevent it from happening.

$tweet = "@wayne how are you? @wayne123 is cool but are you?";

        preg_match_all('/(^|\s)@([a-z0-9_]+)/i', $tweet, $matches);
        $i = 0;

        foreach( $matches[2] as $value ) 
        {   

            if ( $db_query )
            {
                $tweet = str_replace("@" . $value, "<a href=\"/user/$value\">@$value</a>!", $tweet);
            }               
        }

        echo $tweet; // outputs: hi <a href="/user/wayne">@wayne!</a> how are you? <a href="/user/wayne">@wayne!</a>123 is cool but are you?

Any help is greatly appreciated, I have tried with regex before but it continues along the line and updates the others before I am even able to check to see if they are a valid user

The problem is that the first time through your loop @wayne123 is replaced with @wayne so it can't find a match for the second time through the loop.

Use preg_replace with back references.

$tweet = "@wayne how are you? @wayne123 is cool but are you?";
$pattern = '/(^|\s)@(\w+)/';
$replacement = '<a href="/user/$2">@$2</a>';
print preg_replace($pattern, $replacement, $tweet);

in $replacement the $2 is replaced with the match of the second set of parenthesis (\w)

Note that (\w) is the shorthand for ([a-zA-Z0-9_])

add a space?

$tweet = str_replace("@" . $value." ", "<a href=\"/user/$value\">@$value</a>! ", $tweet);

preg_replace is more usefull

I think instead of:

$tweet = str_replace("@" . $value, "@$value!", $tweet);

You should use:

$tweet = preg_replace('/@' . $value.'\b/', "<a href=\"/user/$value\">@$value</a>!", $tweet);