Twitterの発言中に現れるハッシュタグを抜き出す関数
Twitter側がどのようなカタチをハッシュタグと認識するのかよくわからないけど, とりあえず書いてみた. ちなみにめんどくさいので正規表現とかは使ってません.
使い方は:
$ erl 1> twitter_status:hashtags("ほげほげ #banana_#mango#highschool"). ["banana"] 2> twitter_status:hashtags("ふがふが #banana_ #mango #highschool"). ["banana", "mango", "highschool"]
です. 最初の戻り値にmangoとhighschoolが含まれないのはそういう仕様です*1.
んで注意するのは, twitter_status:hashtags/1に与える引数をバイナリまたはUnicode表現のリスト*2にしなければいけない点.
当然と言えば当然なのかもしれませんが, 文字単位で処理を行いたかったので扱いはこっちの方が楽です. 正規表現使ってないし.
ただシェルから与えたリストはあらかじめUnicode表現である*3のに対して, ソース中に書かれたリストはUnicode表現になっていないので:
hoge() -> twitter_status:hashtags("#hoge").
とやっても["hoge"]は返ってきません. list_to_binary/1を使って:
hoge() -> twitter_status:hashtags(list_to_binary("#hoge")).
とすれば, ["hoge"]が返ってきます. バイナリを与えると, twitter_status:hashtags/1がunicode:characters_to_list/1を呼び出すからね!
基本的にバイナリのまま扱っていればいいので, こういうのは稀. とりあえず有事に備えてこの記事を備忘録としよう.
でソースですが, Gistに上がってるのでよければどうぞ.
一応ココにも書いておきます.
-module(twitter_status). -author("KONDO Takahiro <heartery@gmail.com>"). -export([hashtags/1]). -define(ALPHANUMERIC(C), ($a =< C andalso C =< $z orelse $A =< C andalso C =< $Z orelse $0 =< C andalso C =< $9)). -define(HASHTAG_PREFIX(C), (C =:= $# orelse C =:= 65283)). -define(HASHTAG_CHARS(C), (?ALPHANUMERIC(C) orelse C =:= $_)). hashtags(Text) when is_binary(Text) -> hashtags(unicode:characters_to_list(Text)); hashtags(Text) -> lists:reverse(hashtags(Text, -1, "", [])). hashtags([C|Text], -1, [], Hashtags) when ?HASHTAG_PREFIX(C) -> hashtags(Text, 0, [C], Hashtags); hashtags([C|Text], -1, [LC|_] = Read, Hashtags) when ?HASHTAG_PREFIX(C), not ?ALPHANUMERIC(LC) -> hashtags(Text, 0, [C|Read], Hashtags); hashtags([C|Text], Size, Read, Hashtags) when ?HASHTAG_CHARS(C), Size > -1 -> hashtags(Text, Size + 1, [C|Read], Hashtags); hashtags([C|Text], Size, Read, Hashtags) when Size > 0 -> hashtags(Text, -1, [C|Read], [hashtag(Read, Size)|Hashtags]); hashtags([C|Text], Size, Read, Hashtags) -> hashtags(Text, Size, [C|Read], Hashtags); hashtags([], Size, Read, Hashtags) when Size > 0 -> [hashtag(Read, Size)|Hashtags]; hashtags([], _, _, Hashtags) -> Hashtags. hashtag(Read, Size) -> hashtag(Read, Size, []). hashtag(_, 0, Acc) -> Acc; hashtag([C|Read], Size, Acc) -> hashtag(Read, Size - 1, [C|Acc]).