PHP - Creating Links from Plain Text Input

I had added the the ability to turn @user references to links in BeTwittered (Twitter client) quite a while back.  Today, I reused that code to turn #tags to links in BeTwitted and Identify (Laconica clients). Basically the PHP code below takes plain text, looks for #tag references and replaces them with the required HTML to create a link.  This code is not complete as I've not found a specification that defines the characters allowed in a #tag. It does convert the link to lowercase, while leaving the text as was originally typed. This is a very small bit of code, but hopefully it helps someone out.


function make_links_of_hash_references($text){
    global $debug_mode;
    global $srv_url;
   
    preg_match_all("|#[a-zA-Z_0-9\-]*|", $text, $matches);
    foreach($matches as $list){
        foreach($list as $match){
            $atch=ltrim($match, "#");
            $latch=mb_strtolower($atch);
            $text=str_replace($match,"#<a target=\"_blank\" href=\"$srv_url/tag/$latch\" title=\"Go to $srv_url/tag/$latch\">$atch</a>",$text);
        }
    }
    return $text;
}   


Update: Please see the comments for a suggested use of preg_replace() to do this in fewer lines.  It's something I'd hoped to do originally, but could never get it to work.  Thanks Paul!

Comments

@thom Yes! $match and

@thom Yes!
$match and $matches are obvious, from there, I was just entertaining myself with the names.

rtrim(match)=atch
strtolower(atch) made me think latch

I'm just easily entertained, I guess. :)

@Thom heh, far from it. I

@Thom heh, far from it. I just happen to know a bit.

@Paul perl programmer by

@Paul perl programmer by trade?

@robert $matches, $match, $latch, $atch - isn't this just a typo waiting to happen?

Nice! Thanks Paul. I really

Nice! Thanks Paul. I really appreciate you taking the time to think that through an help me out. I'll check this out and play around with it a bit. It'll be satisfying to understand this after struggling with the problem the first time through!

Making part of it lowercase

Making part of it lowercase seems a bit tricky until you realise that preg_replace allows both multiple matches and php code in the matches, when you use the e flag:

$text=preg_replace("/\B#([\w\-]*)\b/e", "'#<a target=\"_blank\" href=\"$srv_url/tag/'.strtolower('$1').'\" title=\"Go to $srv_url/tag/'.strtolower('$1').'\">$1</a>'", $text);

I also adjusted the regular expression slightly so that it doesn't match URLs with hashes in them.

There might be a few small bugs but hopefully this helps you out.

Hi Paul, I actually tried to

Hi Paul,
I actually tried to work this problem through with a preg_match(). Did I miss a more elegant solution? The problem I was having with that solution revolved around handling multiple matches in the given text, then replacing them with the appropriate tag that has embedded in it both a version of the match with a character removed (e.g. '#'), and a version of the match in lowercase. Let me know if you still think I could go with a preg_replace(). I'd love to know if I just gave up too soon! :-)
Thanks,
robert

This seems like a bit of a

This seems like a bit of a long way to do it - would it not be simpler to just use preg_replace and cut it down to one line of code?