Java中的模糊stringsearch库
我正在寻找一个高性能的Java库进行模糊stringsearch。
有许多algorithm可以find相似的string,Levenshtein距离,Daitch-Mokotoff Soundex,n-grams等。
什么Java实现存在? 对他们有利有弊吗? 我知道Lucene,任何其他解决scheme或Lucene是最好的?
我发现这些,有没有人有与他们的经验?
- SimMetrics
- NGramJ
Commons Lang具有Levenshtein距离的实现。
Commons Codec具有soundex和metaphone的实现。
您可以使用Apache Lucene,但根据使用情况,这可能太重。 对于非常简单的模糊search,使用起来可能有点复杂,如果我错了,纠正我需要你build立一个索引。
如果你需要一个简单的在线(=不维护索引)algorithm,你可以使用模糊比特apalgorithm 。 我在这里find了一个Java实现。 它的代码符合一个简单的自我解释签名的相对较短的方法:
public static List<Integer> find(String doc, String pattern, int k)
Apache Commons StringUtils
实现了用于模糊string匹配的Levenshteinalgorithm。 它可以看作是String.equals
的模糊版本,Bitap就像String.indexOf
的模糊版本,仍然使用Levenshtein距离度量。 通常比使用Levenshtein比较search模式和可能匹配的每个子string更有效。
备注 :
- Bitapalgorithm似乎主要用于比较小的字母,例如纯ASCII。 事实上,我链接到的Simon Watiau版本在非ASCII字符(> = 128)上抛出
ArrayIndexOutOfBoundsException
,因此您必须将其过滤掉。 -
我尝试在应用程序中使用Bimap来按名称search内存中的人员列表。 我发现Levenhstein距离为2的错误肯定太多了。 1的Levenhstein距离效果更好,但是在交换两个字母(如“William”和“Willaim”)时无法检测到错字。 我可以想出几个方法来解决这个问题,例如
- 只有当确切search找不到匹配时才进行模糊search(并向用户显示关于此的消息)
- 调整Bitap使用Damerau-Levenshtein距离,其中交换的距离为1,而不是2.根据维基百科 ,这是可能的,但我无法在Java中find现有的实现。
- 而不是“包含”做一个“startsWith”。 模糊search工具包含Damerau-Levenshtein的前缀版本,但它给了我一个
ArrayIndexOutOfBoundsException
- 调整algorithm以引入search结果排名,其中精确匹配得分更高
如果你打算做2或4,最好使用像Lucene这样的正确的全文search库。
- 关于模糊search的更多信息可以在这个博客上find。 它的作者还在Java中创build了一个名为
BitapOnlineSearcher
的实现 ,但要求您将java.io.Reader
与Alphabet类一起使用。 这是Javadoc是用俄语写的。
如果你主要比较短的string,并希望可移植性和轻量级的东西,你可以使用众所周知的pythonalgorithmfuzzywuzzy 移植到Java 。
你可以在这里阅读更多
SimMetrics可能是你所需要的: http : //sourceforge.net/projects/simmetrics/
它有几种algorithm来计算各种风格的编辑距离。
Lucene是一个function非常强大的全文search引擎,但是FTsearch与模糊string匹配不完全相同(例如,给出一个string列表find了与候选string最相似的列表)。
到Lucene我会添加SOLR http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters
你可以试试bitap。 我正在用ANSI C写的bitap,而且速度很快,在http://www.crosswire.org上有java实现。;
我认为, Apache Lucene是唯一的方法。 我不知道有什么更好的search库。
Apache Lucene(TM)是一个高性能,全function的文本search引擎库,完全用Java编写。 它几乎适用于任何需要全文search的应用程序,特别是跨平台的应用程序。
您可以尝试完全库,它依靠文本预处理来创build内存索引,以便在大型数据集中有效地应答(模糊)search。 与Lucene和其他function齐全的文本search库不同的是,API体积小,易于上手。