アジョブジ星通信

日常系バンザイ。

ツイートに含まれるURLを高速に抽出するライブラリ、つくりました

2016/03/13 お知らせ: このライブラリの内容を含めて twitter-text 完全互換のライブラリを作りました。こっちがメインになります。

お知らせ終わり。

URI教の皆さんへ: Twitter が URL って言ってるからこっちに統一しました。許して。

はい、タイトルの通りです。言いたいことは以上です。

twitter-text 問題

神(Twitter)は言われた。「ライブラリあれ。」こうして、 twitter-text があった。神は twitter-text を見て、良しとされた。

「よくねーよ C# 版出してくれよ!」

こんな声にお答えしたライブラリは数あれど(メンテナンスされてるとは言ってない)、そもそも twitter-text の Extractor(URLとかハッシュタグとか抽出してくるやつ)は正規表現頼りで、連続して動かすと非常に遅いわけです。

そもそも、 Twitter クライアント作者(僕は違う、よね)が twitter-text を求めるのは、あのクソみたいな t.co とかいうやつを考慮してツイートの文字数を計算し、 140 文字をオーバーしていないかをチェックするためですよね。つまりこのクソ長い正規表現を 1 文字入力するたびに走らせなければなりません。おえー

正規表現は文字列を順番に読み進み、一致しなければ少し戻り、をマッチする/しないが確定するまで繰り返します。単純な文字列ならいいんですけどね、 t.co の判定基準とかだるすぎるし、人間にとってだるいんだから、コンピュータにとってはつらすぎますよね。知らんけど。

そこで、つくりました

Azyobuzi.TwitterUrlExtractor(かっこいい名前が思いつかなかった)は、最も効率的な方法(だと僕が思っている方法)で URL を抽出します。これでツイート内容のテキストボックスに「ああああああああああああ(x1000くらい)」と無駄に入力しても重くならないようになりますね!

仕組みは簡単(ではない)。

  1. 「.」を探す (http://twitter.(←)com/azyobuzin)
  2. 逆戻りしてドメインとして有効な部分と「http://」があるかないかを探す ((→)http://twitter.com/azyobuzin)
  3. 「.」の後ろもドメインとして有効な部分を探す (http://twitter.com(←)/azyobuzin)
  4. 有効な TLD かどうかチェック
  5. ポート・パス・クエリを読み取る
  6. 完了!

と書くのは簡単だけど、イレギュラーな判定基準が多すぎて死にそうになりましたが、見事 twitter-text に入ってる extract.yml のテストを全部通過させることができました!

まとめ

(たぶん)twitter-text 互換の URL 検出を結構高速(twitter-text-csの17倍, Releaseビルドだともっとやばい)に行うことができます。強い!

感想


追記