5

我想检查关键字字符串是否包含在文本字符串中。这一定是一个模糊的包含。

我的第一次尝试是使用库blurwuzzy。当使用部分比率时字符串差异很大时,这似乎具有产生高匹配值的意外行为。

我尝试使用 levenshtein 的距离,它可以将一个字符串与另一个字符串进行比较,但不能用于查找字符串是否包含关键字。
我尝试的一个想法是将文本拆分为单个单词,然后遍历它们,计算距离以查看是否匹配。问题是关键字中可能有空格,这意味着使用此方法找不到任何匹配项。

我现在尝试使用 Bitap 算法来查找关键字是否在文本中,但是当关键字和文本非常不同时,这会返回为真。该算法可以在这里找到。

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 索引的情况下执行模糊包含,这将非常有用。

最好的方法是什么?

4

1 回答 1

4

我前段时间也遇到过同样的问题。要求是检测并删除包含在系统中注册为阻止的 url 的传入文本。

但是它们不会 100% 匹配,因为传入文本的检测是通过 OCR 算法完成的。

假设我们有一个被阻止的字符串“www.blockedwebsite.com”和一个传入的字符串“我喜欢网站 www.blockdwebsite.com :)”(注意 'e' 已从 url 中删除)。由于“我喜欢这个网站”,计算 levenshtein 距离会导致距离很大,所以不匹配。(我使用 apache.commons.similarity.LevenshteinDistance 库)

我所做的是遍历传入的字符串,将子字符串从 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% 匹配或类似的内容。我希望这有帮助。祝你好运。

于 2018-05-18T09:22:54.943 回答