JavaScriptでいい感じにURLとかScreenNameとかをリンクにする正規表現

URLに@が入ってたりすると、ScreenNameのリンクとごっちゃになって割と対応に手間取ったのでメモとして。日本語のハッシュタグなんか最近見かけないからどうでもいいような気もするけど、まぁ一応対応。

var text="@xyz aaa http://aaa.com:8080/@abc#asdf http://日本語.jp/?abc&asdf http://example.jp/a.b.c@d.e bbb @ccc/@ddd/@eee #hash #日本語だめ #日本語おk_ http://a.com/日本語";
text.replace(/(https?:\/\/(?:[^!"#$%&amp;'\(\)*\+,-\./:;<=>\?@\[\\\]^_`\{\|\}~\s][\.-](?=[^!"#$%&amp;'\(\)*\+,-\./:;<=>\?@\[\\\]^_`\{\|\}~\s])|[^!"#$%&amp;'\(\)*\+,-\./:;<=>\?@\[\\\]^_`\{\|\}~\s]){1,}\.[a-z]{2,}(?::[0-9]+)?(?:\/(?:[\x21-\x7e]+)?)?)|(?:[@@])([a-z0-9_]{1,20})|(?:#|\uFF03)([^\s\/ \x21-\x2f\x3a-\x40\x5b-\x5e\x60\x7b-\x7e]+[a-z0-9_])/mgi, function(){
 if(arguments[1]!==""){
  return "<a class='url' href='"+arguments[1]+"'>"+arguments[1]+"</a>";
 }else if(arguments[2]=="" &amp;&amp; arguments[3]==""){
  return arguments[1];
 }
 if(arguments[2]!==""){
  return "<a class='screen_name' href='http://twitter.com/"+arguments[2]+"'>@"+arguments[2]+"</a>";
 }else if (arguments[3]==""){
  return arguments[2];
 }
 if (arguments[3]!==""){
  return "<a class='hashtag' href='http://search.twitter.com/search?q=%23"+arguments[3]+"'>#"+arguments[3]+"</a>";
 } else {
  return arguments[3];
 }
}
)

実行すると

"<a class='screen_name' href='http://twitter.com/xyz'>@xyz</a> aaa <a class='url' href='http://aaa.com:8080/@abc#asdf'>http://aaa.com:8080/@abc#asdf</a> <a class='url' href='http://日本語.jp/?abc&amp;asdf'>http://日本語.jp/?abc&amp;asdf</a> <a class='url' href='http://example.jp/a.b.c@d.e'>http://example.jp/a.b.c@d.e</a> bbb <a class='screen_name' href='http://twitter.com/ccc'>@ccc</a>/<a class='screen_name' href='http://twitter.com/ddd'>@ddd</a>/<a class='screen_name' href='http://twitter.com/eee'>@eee</a> <a class='hashtag' href='http://search.twitter.com/search?q=%23hash'>#hash</a> #日本語だめ <a class='hashtag' href='http://search.twitter.com/search?q=%23日本語おk_'>#日本語おk_</a> <a class='url' href='http://a.com/'>http://a.com/</a>日本語"

という文字列になり、以下のようにほぼ思ったとおりのリンクになる

@xyz aaa http://aaa.com:8080/@abc#asdf http://日本語.jp/?abc&asdf http://example.jp/a.b.c@d.e bbb @ccc/@ddd/@eee #hash #日本語だめ #日本語おk_ http://a.com/日本語

ドメインじゃなくてPATH部分に日本語が含まれる、WikipediaのURLみたいなのには対応してない。やりゃできるけど、TwitterでURLを投げるときに、URLの後ろにスペースいれないで日本語を続けて入れる人も割といそうなので…とりあえずこれでいいかな、とか。

なんかもっと美しく簡単にできそうな気もするんだけど…誰か添削してください。