Try this little puppy:
preg_replace("(\r\n|\n|\r)", "<br />", preg_replace(array("/(([\w\.]+))(@)([\w\.]+)\b/i", "/((ftp(7?):\/\/)|(ftp\.))([\w\.\/\&\=\?\-]+)/", "/((http(s?):\/\/)|(www\.))([\w\.\/\&\=\?\%\#\-]+)/"), array("<a href=\"mailto:$0\">$0</a>", "<a href=\"ftp$3://$4$5\" target=\"_blank\">ftp$3://$4$5</a>", "<a href=\"http$3://$4$5\" target=\"_blank\">http$3://$4$5</a>"), $text))
As far as I've been able to determine, this works like a charm on pretty much anything - emails, URLs and ftp addresses.
Of course it isn't exactly "small" 😉
Also as a p.s., I've noticed when copying and pasting out of postings on this board, the space characters tend to get transformed into something that PHP doesn't like - I usually just go through and replace them with hand-typed spaces.