tags:

views:

46

answers:

3

i am designing a site with a comment system and i would like a twitter like reply system.

The if the user puts @a_registered_username i would like it to become a link to the user's profile.

i think preg_replace is the function needed for this.

$ALL_USERS_ROW *['USERNAME'] is the database query array for all the users and ['USERNAME'] is the username row.

$content is the comment containing the @username

i think this should not be very hard to solve for someone who is good at php.

Does anybody have any idea how to do it?

+1  A: 

You want it to go through the text and get it, here is a good starting point:

$txt='this is some text @seanja';

$re1='.*?'; # Non-greedy match on filler
$re2='(@)'; # Any Single Character 1
$re3='((?:[a-z][a-z]+))';   # Word 1

if ($c=preg_match_all ("/".$re1.$re2.$re3."/is", $txt, $matches))
{
      $c1=$matches[1][0];
      $word1=$matches[2][0]; //this is the one you want to replace with a link
      print "($c1) ($word1) \n";
}

Generated with:

http://www.txt2re.com/index-php.php3?s=this%20is%20some%20text%20@seanja&-40&1

[edit]

Actually, if you go here ( http://www.gskinner.com/RegExr/ ), and search for twitter in the community tab on the right, you will find a couple of really good solutions for this exact problem:

$mystring = 'hello @seanja @bilbobaggins [email protected] and @slartibartfast';
$regex = '/(?<=@)((\w+))(\s)/g';
$replace = '<a href='http://twitter.com/$1' target="_blank">$1</a>$3';
preg_replace($regex, $replace, $myString);
SeanJA
Obviously you want to do this before it hits the database...
SeanJA
fixed the regex in the second one so that it does not match emails.
SeanJA
+2  A: 
$content = preg_replace( "/\b@(\w+)\b/", "http://twitter.com/$1", $content );

should work, but I can't get the word boundary matches to work in my test ... maybe dependent on the regex library used in versions of PHP

 $content = preg_replace( "/(^|\W)@(\w+)(\W|$)/", "$1http://twitter.com/$2$3", $content );

is tested and does work

Devin Ceartas
I concur, that does work, except it seems to match the space after the @word for some reason (at least when I check it with http://www.gskinner.com/RegExr/ )
SeanJA
it matches the space after, yes, and the one before (to check that the @ isn't in the middle, like an email address). That's why I put both spaces back in ($1 and $3) in the replacement value.
Devin Ceartas
Ah, a good solution to the problem that my second example has
SeanJA
Regex is fun, and since I'm old and perl is my first language, they sort of run in my blood. This book is truly one of the best tech books I've ever read, I recommend it highly: http://www.amazon.com/Mastering-Regular-Expressions-Jeffrey-Friedl/dp/0596528124/
Devin Ceartas
A: 
$str = preg_replace('~(?<!\w)@(\w+)\b~', 'http://twitter.com/$1', $str);

Does not match emails. Does not match any spaces around it.

Geert