Java中的模糊字符串搜索库

Java中的模糊字符串搜索库,java,nlp,fuzzy-search,Java,Nlp,Fuzzy Search,我正在寻找一个用于模糊字符串搜索的高性能Java库 有许多算法可以找到类似的字符串,如Levenshtein距离、Daitch-Mokotoff Soundex、n-grams等 存在哪些Java实现?他们的利弊?我知道Lucene,还有其他解决方案或Lucene是最好的吗 我发现了这些,有没有人有经验 我认为这是唯一的办法。我不知道还有什么更好的搜索库 ApacheLucene(TM)是一个完全用Java编写的高性能、全功能文本搜索引擎库。这项技术几乎适用于任何需要全文搜索的应用程序,尤

我正在寻找一个用于模糊字符串搜索的高性能Java库

有许多算法可以找到类似的字符串,如Levenshtein距离、Daitch-Mokotoff Soundex、n-grams等

存在哪些Java实现?他们的利弊?我知道Lucene,还有其他解决方案或Lucene是最好的吗

我发现了这些,有没有人有经验

    • 我认为这是唯一的办法。我不知道还有什么更好的搜索库

      ApacheLucene(TM)是一个完全用Java编写的高性能、全功能文本搜索引擎库。这项技术几乎适用于任何需要全文搜索的应用程序,尤其是跨平台的应用程序


      Commons Lang有一个的实现


      Commons编解码器具有和的实现。

      SimMetrics可能是您所需要的:

      它有几个算法来计算各种风格的编辑距离


      Lucene是一个功能非常强大的全文搜索引擎,但FT搜索与模糊字符串匹配并不完全相同(例如,给定字符串列表,找到与某个候选字符串最相似的字符串)。

      您可以尝试bitap。我玩的是用ANSIC编写的bitap,它非常快,有java实现

      对于Lucene,我会添加SOLR

      您可以使用ApacheLucene,但根据具体的使用情况,这可能太重了。对于非常简单的模糊搜索,它的使用可能有点复杂(如果我错了,请纠正我),它需要您建立一个索引

      如果您需要一个简单的在线(=不维护索引)算法,您可以使用模糊算法。我发现了一个Java实现。它的代码适用于一个相对较短的方法,具有几乎自我解释的签名:

      public static List<Integer> find(String doc, String pattern, int k)
      
      公共静态列表查找(字符串文档、字符串模式、int k)
      
      apachecommons
      StringUtils
      实现了用于模糊字符串匹配的Levenshtein算法。它可以看作是
      String.equals
      的模糊版本,Bitap类似于
      String.indexOf
      的模糊版本,仍然使用Levenshtein距离度量。它通常比单纯地使用Levenshtein来比较搜索模式与可能匹配的每个子字符串更有效

      注释

      • Bitap算法似乎对相对较小的应用程序最有用 字母表,例如普通ASCII。事实上,我链接到的Simon Watiau版本在非ASCII字符(>=128)上抛出了一个
        ArrayIndexOutOfBoundsException
        ,因此您必须过滤掉这些字符
      • 我尝试在应用程序中使用Bimap按姓名搜索内存中的人员列表。我发现Levenhstein距离为2 漏报太多。1的Levenstein距离有效 更好,但它无法检测到您交换两个字母的打字错误,例如。 “威廉”和“威廉”。我可以想出一些办法来解决这个问题, e、 g

      • 仅当精确搜索未找到匹配项时才执行模糊搜索(并向用户显示有关此项的消息)
      • 调整Bitap以使用Damerau Levenshtein距离,其中交换的距离为1而不是2。根据,这是可能的,但我找不到现有的Java实现
      • 而不是“包含”做一个“startsWith”。包含Damerau Levenshtein的前缀版本,但它给了我一个
        ArrayIndexOutOfBoundsException
      • 调整算法,引入搜索结果排名,精确匹配得分更高
      • 如果你打算做2或4,它可能会 最好使用合适的全文搜索库,如Lucene 无论如何

      • 有关模糊搜索的更多信息,请访问。是作者 还创建了一个名为
        BitapOnlineSearcher
        , 但是需要将
        java.io.Reader
        与字母表一起使用 班级。它是用俄语写的Javadoc

      如果您主要比较短字符串,并且想要一些可移植且轻量级的东西,那么您可以使用众所周知的python算法fuzzywuzzy


      您可以阅读更多有关它的信息

      您可以尝试该库,它依靠文本预处理来创建内存索引,以便在大数据集中高效地回答(模糊)搜索。与Lucene和其他全功能文本搜索库不同,该API体积小且易于启动。

      simmetrics看起来是GPL v2,但与商业开发的软件不兼容。存在“重写”问题在GitHub上,有一个有待解决的许可问题:@DanHaywood从版本3.2.3开始,许可证已更改为Apache版本2。0@pppeater从3.2.3版开始,许可证已更改为Apache 2.0版,不能对其他版本发表评论,但我发现commons langs Levenshtein的距离对于模糊等式检查很有用,不是模糊的。不幸的是,您仍然需要编写自己的算法来使用它。这仍然需要一些努力才能正确完成(您必须匹配源字符串中的不同长度)并具有良好的性能(bitap可能比仅使用Levenshtein距离编写的要快得多)。@Hennovermelen如果您找到任何解决方案,请与我们分享?有没有用java实现bitap?我对这个问题的回答包含一个指向java实现的链接(事实上,这是我在谷歌搜索“java bitap”时找到的第一个),用于寻找一个简单的模糊搜索,该搜索实际上从字符串返回匹配的子字符串,而不是分数,这里有一个要点:。编辑:@sukhmel我已更新了此评论中的链接(删除了旧链接)。如果它再次发生,我的回购协议中应提供要点:请提供代码和任何相关文档的直接链接。有一种方法可以只对字母数相同的单词进行Bitap搜索,例如,如果我搜索k=2的名称,Namo和Mamo被接受,但Nam不被接受?只是使用fuzzywuzzy有非常积极的体验。比较了2的集合中的几个字符串