(?:www|ftp\.)?|www|ftp\.)

In this section of your regex you should be matching . outside of the brackets. At the moment that will match "www" or "ftp.", not "www." or "ftp." like it should.

It would also be a good idea to match a single digit directly after "www" so that it will work with things like "www2.google.com"

Updated regex:

Code:
\b(?:(?:htt|ft)ps?://(?:www\d?\.|ftp\.)?|www\d?|ftp)\..*(?:\.[a-z]{2,4})(?::\d+)?(?:/\w+(?:/\w*/*)*|(?:\.[a-z]{2,4})|\?\S*)*\b