logo

Automatically linking Twitter @usernames in PHP

logo

I keep seeing people writing scripts that embed their Twitter feed into their websites. The “easy” way is to use Javascript, which means you don’t need to have PHP installed on your server. Doing it this way means your tweets will not be visible to visitors with Javascript disabled.

Really, nobody has Javascript disabled in their browsers anymore. The web is pretty much inaccessible without it at this point. However there are still some very important “visitors” that crawl around the web without javascript. I’m talking about search engines. Few if any search engines will actually execute Javascript on your site when crawling it for content. This means anything you have hidden inside a <script> tag will be hidden to them. If you want your tweets to be indexed as part of your page, then you’ll need to use PHP or another server-side scripting language to embed them into your page. This also has the other advantage of making your page load faster to regular visitors as well.

The below diagram should help illustrate the benefit of using PHP to embed your tweets.

Now that you’re convinced that you want to use PHP to embed your Twitter posts, you’re going to quickly run into the problem that people’s Twitter usernames are not given as a link in the RSS feed, but just the @username text. You probably want these usernames linked back to twitter.com.

I have seen some solutions involving splitting up the tweet into individual words, and looking at each to see if it begins with an @ sign. This involves a lot of code, and generally looks something like this:

It is rendered completely unnecessary by using one line of regular expressions!

$tweet = preg_replace('/(^|[^a-z0-9_])@([a-z0-9_]+)/i', '$1<a href="http://twitter.com/$2">@$2</a>', $tweet);

This regular expression is actually pretty simple. (updated) The key part is “(^|[^a-z0-9_])@([a-z0-9_]+)”, which is a lot less scary than it first looks. The ( ) are used to capture what’s inside them so that you can access it later (by using the $1 and $2 above). The [ ] match a set of characters, which can be defined as a range or a list of characters. We’re matching numbers and letters and the underscore. Finally, the + says “one or more”. The vertical bar | is used to match either what’s on the left or what’s on the right. The caret ^ (if it’s not inside square brackets) matches the beginning of a line.

So in English, this regular expression is looking for either the start of a line or a character other than a letter or number or underscore, followed by an @ sign, followed by one or more numbers or letters or the underscore, and storing those characters in the variable $2. This string is then replaced with the HTML code you see above, where $2 is set to the username by the regular expression.

Now that you understand the regular expression above, let me further complicate things by showing you how to make text that begins with http:// into a real hyperlink.

$search = array('|(http://[^ ]+)|', '/(^|[^a-z0-9_])@([a-z0-9_]+)/i');
$replace = array('<a href="$1">$1</a>', '$1<a href="http://twitter.com/$2">@$2</a>');
$tweet = preg_replace($search, $replace, $tweet);

Trust me, it isn’t that bad really. The new regular expression is actually simpler than the first, but is looking for http:// instead of @. You may have also noticed that I switched from using // to ||. You can use any character as the bounds for the regular expression. The advantage of using | is that the bar doesn’t appear inside ever. If I used / as the bounds, then had http:// inside, I’d have to escape the forward slashes of the http. (It would look like http:\/\/, which is kind of ridiculous).

You might want to check out http://www.regular-expressions.info to learn more about regular expressions. Regular expressions are an extremely powerful tool you will want to add to your arsenal when learning PHP.

70 Responses to “Automatically linking Twitter @usernames in PHP”

  1. [...] links (http://). Its whole lot less code and a whole lot easier. You can read his addition to this here. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 [...]

  2. Matt says:

    Nice post! I’d like to offer one alternative to your expression if you don’t mind. Sometimes in text you’ll see the following kind of status update:

    @Joe: I am eating lunch with @Jane.

    The regular expression you’re using here would catch @Joe: and @Jane. but the colon and period aren’t part of their usernames. Twitter’s usernames can only be alphanumeric or include the underscore.

    If you change the expression to:
    @([\w_]+)

    then you will then only get the username and avoid characters like colon’s, period’s, etc…

    Cheers.

  3. aaron says:

    @Matt: Good thinking. I’ve updated the post accordingly! I actually used [0-9a-Z_] as the character class because I like being more explicit for readability’s sake.

  4. Remco Tolsma says:

    @aaron The second example is not working correctly. You should first replace the links within the tweet and then the @username.

    $search = array(‘|(http://[^ ]+)|’, ‘|@([0-9a-z_]+)|’);
    $replace = array(‘$1‘, ‘@$1‘);

  5. aaron says:

    @Remco thanks for catching that. I’ve updated the post.

  6. Cometbus says:

    Even with the fixes in the comments, consider this:

    @cometbus have you seen @ahem’s last tweet? You can email me at foo@example.com. #contactme@email.

    You will get :
    @cometbus
    @ahem
    @example
    @email

  7. aaron says:

    @cometbus

    That actually just occurred to me the other day when I was writing some code to parse some text that has an equal chance of containing Twitter usernames as it does email addresses. Typically tweets don’t contain email addresses so it isn’t usually a problem.

    Here is my updated regex.

    preg_replace(‘/(^|[^a-z0-9_])@([a-z0-9_]+)/i’, ‘$1<a href=”http://twitter.com/$2″ >@$2</a>’, $tweet);

    This requires either a non-alphanumeric character preceding the @ sign, or matches the username at the beginning of the line.

  8. larry says:

    Don’t forget to include A-Z in the for capitalized letters

  9. Ferodynamics says:

    I doubt Twitter scans their database to see if a username actually exists (before linking to it) because that would slow things down. I saw a tweet today on Twitter’s website: “sold @2.45″ meaning “sold at $2.45″ and Twitter assumed this was user “2″ cut off at the period. Twitter.com/2 actually exists, which is all the more tragic. So if I incorrectly match an email address, I hereby apologize in advance ;-)

  10. aaron says:

    @larry: the /i flag makes the regex case-insensitive, so it’s not necessary to include A-Z. /[a-zA-z]/ and /[a-z]/i are equivalent expressions.

  11. Hey man – thanks a lot for this. You helped me understand regex a lot better. Hopefully will have it working properly on allaboutchris.co.uk soon!

  12. thanking you! says:

    thanks. just what i needed. works perfectly =)

    thank you.

  13. Gavin says:

    helped me solve a problem I was having with my own twitter parser, cheers :)

  14. This is just what I was looking for. Do you happen to have a modified version that does the same but for twitter hash tags? So “#example” would be replaced with #example that is linked to “http://twitter.com/#!/search/%23example”

    Thank you!

  15. aaron says:

    I haven’t tested this, but you might try replacing the @ with a # and it should work pretty well. You’ll also need to change the link that is drawn. Try this:

    $search = array('|(http://[^ ]+)|', '/(^|[^a-z0-9_])@([a-z0-9_]+)/i', '/(^|[^a-z0-9_])#([a-z0-9_]+)/i');
    $replace = array('<a href="$1" rel="nofollow">$1</a>', '$1<a href="http://twitter.com/$2" rel="nofollow">@$2</a>', '$1<a href="http://twitter.com/search/%23$2" rel="nofollow">#$2</a>');
    $tweet = preg_replace($search, $replace, $tweet);
  16. Awesome, I’ll give it a shot! Good call with the no follow as well.

  17. Air Max 93 says:

    Because of reading your blog, I decided to correspond with my own. I had at no time been interested in keeping a blog until I slogan how considerate yours was, then I was inspired!

  18. If you are looking for an effective way to get YouTube video views from REAL people, I have a great news for you …

  19. Boston Limo says:

    Just want to say your article is as amazing. The clearness in your post is just cool and i can assume you are an expert on this subject. Fine with your permission allow me to grab your feed to keep updated with forthcoming post. Thanks a million and please carry on the enjoyable work.

  20. bizarre says:

    Almost all of whatever you state is supprisingly legitimate and it makes me wonder the reason why I had not looked at this in this light previously. This particular piece really did turn the light on for me as far as this specific issue goes. Nonetheless at this time there is 1 position I am not too comfortable with and while I try to reconcile that with the actual central idea of the point, allow me observe exactly what the rest of your readers have to point out.Nicely done.

  21. cool aides says:

    Such a great place to find exacly what i was searching for

  22. Hello. I happened upon your site while I was looking for something completely unrelated. While I do not agree with everything you said we do have similar thoughts by and large. I have bookmarked your web site and will visit again in the near future to see what you are writing about in 2010!

  23. Photo Mania says:

    Really enjoyed your site!

  24. Mike Kohn says:

    Awesome! I’m using the version you suggested in the comments that includes hash tags, and it’s working perfectly. Thanks for the great tip!

  25. creed only says:

    Lets face it. The size of your penis plays a HUGE role in your self-confidence and self esteem. Like it or not guys with that exceptional manhood dangling from their pants have the confidence to take on anything and then some. If youve been feeling small all your life and want some REAL solutions to banish your size woes then this article is for you! Read on and learn about 3 popular enlargement options and whether they are really effective in transforming your manhood.

  26. Pim Schaaf says:

    Thanks! Used parts of your description to match and validate Twitter usernames in PHP. Slightly adjusted the pattern to match ‘@usernames’ only, adding a $ to the end to prevent ‘@username derp’ from matching.

    pattern: /^@([A-Za-z0-9_]+)$/i

  27. Get Fit With says:

    There are some interesting cut-off dates in this article however I don’t know if I see all of them heart to heart. There may be some validity however I’ll take maintain opinion till I look into it further. Good article , thanks and we wish extra! Added to FeedBurner as nicely

  28. Barbee1501 says:

    You guys really think that? I never try to look at things that way.

  29. Check this…

    Read this posting from the good friends……

  30. I’d forever want to be update on new articles on this internet site , saved to favorites ! .

  31. My coder is trying to convince me to move to .net from PHP. I have always disliked the idea because of the costs. But he’s tryiong none the less. I’ve been using WordPress on a number of websites for about a year and am concerned about switching to another platform. I have heard very good things about blogengine.net. Is there a way I can transfer all my wordpress content into it? Any help would be greatly appreciated!

  32. BG mail says:

    Great web site. Lots of helpful information here. I’m sending it to a few buddies ans also sharing in delicious. And of course, thank you on your sweat!

  33. Aw, this was a very nice post. In concept I wish to put in writing like this moreover – taking time and actual effort to make an excellent article… but what can I say… I procrastinate alot and under no circumstances appear to get one thing done.

  34. Great information it is really. My father has been awaiting for this information.

  35. I wish to show my thanks to this writer just for rescuing me from this particular scenario. After checking through the the net and seeing things that were not beneficial, I believed my entire life was done. Living without the presence of answers to the difficulties you have solved through your good blog post is a critical case, and those which could have badly damaged my entire career if I hadn’t come across your web site. Your main competence and kindness in controlling all the details was helpful. I’m not sure what I would’ve done if I had not discovered such a solution like this. I can at this point look forward to my future. Thanks for your time very much for this impressive and sensible guide. I will not think twice to refer the sites to anybody who should have support about this topic.

  36. Hello my friend! I want to say that this article is amazing, nice written and include approximately all significant infos. I would like to peer extra posts like this.

  37. Find Work says:

    I like what you guys are up too. Such clever work and reporting! Carry on the superb works guys I have incorporated you guys to my blogroll. I think it’ll improve the value of my site :) .

  38. stationery says:

    I would like to thank you for the efforts you have put in writing this site. I’m hoping the same high-grade site post from you in the upcoming as well. Actually your creative writing skills has encouraged me to get my own web site now. Actually the blogging is spreading its wings fast. Your write up is a good example of it.

  39. An impressive share, I simply given this onto a colleague who was doing just a little analysis on this. And he in fact purchased me breakfast as a result of I found it for him.. smile. So let me reword that: Thnx for the deal with! But yeah Thnkx for spending the time to discuss this, I feel strongly about it and love studying more on this topic. If doable, as you grow to be experience, would you thoughts updating your weblog with more details? It’s extremely useful for me. Large thumb up for this weblog post!

  40. Hi there I am so happy I found your website. A quick question if you don’t mind. I’m really enjoying the design and layout of your site. It’s a very easy on the eyes which makes it easy to follow for me to come here and visit more often. Did you hire out a designer to create your theme? Superb work!…

  41. Tori Puleio says:

    I like the valuable information you supply inside your articles. I will bookmark your weblog and check again here regularly. I am quite confident I will learn plenty of new stuff correct here! Excellent luck for the next!

  42. I am glad to be a visitant of this utter weblog, appreciate it for this rare information!

  43. thongs women says:

    Hi there, I found your website via Google while searching for a related topic, your website came up, it looks good. I’ve bookmarked it in my google bookmarks.

  44. piano says:

    I found your weblog site on google and test just a few of your early posts. Proceed to maintain up the very good operate. I just further up your RSS feed to my MSN Information Reader. Searching for ahead to studying more from you afterward!…

  45. Hello, you used to write wonderful, but the last few posts have been kinda boring… I miss your super writings. Past few posts are just a little bit out of track! come on!

  46. Thanks, I have recently been looking for information about this subject matter for ages and yours is the best I have discovered so far.

  47. And Im running from a regular users account with strict limitations, which I believe may be the limiting factor, but Im running the cmd as the system I am currently working on.

  48. You should take part in a contest for one of the best blogs on the web. I will recommend this site!

  49. You made some respectable points there. I regarded on the internet for the issue and located most individuals will go together with together with your website.

logo
logo
Powered by WordPress | Designed by Elegant Themes