我想检查文本字符串中是否包含关键字字符串。这必须是模糊包含的。
我的第一次尝试是使用库fuzzywuzzy。当使用部分比率时,当字符串差异很大时,这似乎具有产生高匹配值的意外行为。
我尝试过使用levenshtein的距离来比较一个字符串到另一个字符串,但不是用于查找字符串是否包含关键字。
我尝试过的一个想法是将文本分成单个单词然后循环遍历所有计算距离以查看是否存在匹配。问题是关键字可能在其中有空格,这意味着它不会使用此方法找到任何匹配项。
我现在尝试使用Bitap算法来查找关键字是否在文本中,但当关键字和文本非常不同时,这会返回true。可以找到该算法here.
final String keyword = "br0wn foxes very nice and hfhjdfgdfgdfgfvffdbdffgjfjfhjgjfdghfghghfg".toLowerCase();
final String text = "The Quick Brown Fox Jumps Over the Lazy Dog".toLowerCase();
final Bitap bitap = new Bitap(keyword, alphabet);
bitap.within(text, 20); // Returns true
我研究过使用Lucene。这样做的问题在于,很多都是基于从所有数据创建索引然后执行搜索。在我的情况下,这不能完成,因为它需要一个单独采用关键字和文本的方法。如果有任何资源与执行模糊包含而不使用Lucene进行索引,那将非常有用。
最佳方法是什么?
答案 0 :(得分:1)
我前一段时间遇到过同样的问题。 要求是检测并删除包含在系统中注册为已阻止的URL的传入文本。
然而,它们不匹配100%,因为传入文本的检测是通过OCR算法完成的。
假设我们有一个被阻止的字符串“www.blockedwebsite.com”和一个传入的字符串“我喜欢网站www.blockdwebsite.com :)”(注意'e'已从网址中删除) 。由于“我喜欢网站”,计算levenshtein距离会产生很大的距离,因此不匹配。 (我使用apache.commons.similarity.LevenshteinDistance库)
我做的是迭代传入的String,将i的子字符串转换为被阻塞字符串的长度。
LevenshteinDistance ld = LevenshteinDistance.getDefaultInstance();
String incomingString = "I like the website www.blockdwebsite.com";
String blockedString = "www.blockedwebsite.com";
for (int i = 0; i < incomingString.length()-blockedString.length(); i++) {
String substring = incomingString.substring(i, i+blockedString.length());
Integer distance = ld.apply(substring, blockedString);
if (distance < 5)
System.out.println("match found");
}
当距离低于5时,检测到匹配。您可以将此更改为90%匹配或类似的东西。 我希望这有帮助。祝你好运。