Regexp::Trie を java に移植した
https://github.com/tokuhirom/regexp-trie
Regexp::Assemble っぽいことをするには graph-expression に入ってるやつを使えばいい、という話は昨日書いた のですが、生成コードがあまり綺麗ではないし、まあ今どき google-collections に依存しているところからも分かる通り、メンテナンスはされていないようです。
というわけで、@dankogai の Regexp::Trie を java に移植してみました。
使い方は以下の様になります。Perl5 とほぼ同じ感じで使えていますね(例は例によって groovy)。
@GrabResolver(name='tokuhirom', root='https://tokuhirom.github.io/maven/releases/')
@Grab('me.geso:regexp-trie:0.0.1')
import me.geso.regexp_trie.RegexpTrie;
def trie = new RegexpTrie();
["foobar", "fooxar", "foozap", "fooza"].forEach {
trie.add(it);
}
println(trie.regexp()) // → (?:foo(?:bar|xar|zap?))
依存もないし、シンプルなコードなので使いやすいと思います。
必要な JDK バージョンは 7 です。
コードは Perl 版に比べて長くなっているが、読みやすくなっていると思います。 長くなってる感じがするのは、元のコードが dan さんのコードなので、めっちゃ詰めて書いてあるからというのもでかい。
今回、唯一詰まったのは、
TreeMap<String, TreeMap<String, TreeMap<String, ...>
みたいな再帰的な型をどうやって定義しようかな、というところだったのですが、これは
class CharTrie extends TreeMap<String, CharTrie> { }
とすればよいのでした。
あと、当初は Character 型を Trie のキーにしていたのだが、null は TreeMap の key に使えないということに気づいたので、String 型に変更し、terminator は "" で表現することに変更しました。 (本当は Terminator オブジェクトとツリーオブジェクトを定義する方が Java らしいのかもしれないけど、めんどくさいし今動いてるのでいいということにします。もっと Java らしくてかっこいい設計が思いつく人がいたら教えてほしいです。)
Published: 2014-11-28(Fri) 08:09