在完全匹配 C# 的文本中查找所有关键字及其索引

本文关键字:查找 关键字 索引 文本 | 更新日期: 2023-09-27 18:36:38

我有一个关键字列表和一个文本来搜索它们。我需要获取文本中每个找到的关键字的开始索引,并且匹配必须准确。例如:

keywords=>cat,dog
text=> a catchy cat with a dogged dog
在这里,虽然只匹配"猫"和"

狗",但必须返回与索引的匹配,并且不应使用"朗朗上口"和"顽固"之类的词进行匹配

我已经尝试过 Aho-Corasick 算法进行字符串匹配,但它也匹配"朗朗上口"和"顽固"。如何使用 c# 对关键字进行精确匹配并返回文本中的索引位置

在完全匹配 C# 的文本中查找所有关键字及其索引

使用带有边界的正则表达式。

var results= keywords.Select(x=>
                               new
                               {
                                word=x,
                                indexes=Regex.Matches(input,@"'b"+x+@"'b")
                                             .Cast<Match>().Select(y=>y.Index)
                                             .ToList()    
                               }
                            );

您现在可以迭代结果

foreach(var match in results)
{
    match.word;
    foreach(int index in match.indexes)//index
}

您可以使用 Aho-Corasick 算法进行一些修改。对于所有关键字,请附加单词分隔符(例如空格,点,换行符等)到每个关键字的末尾。

因此,如果您有 m 个关键字并且文本有 n 种类型的分隔符,您将从 n*m 个单词构建 trie 树。

附加分隔符后,它将与您的示例案例中的"朗朗上口"和"顽固"不匹配。

编辑:

首先,您最好了解AC算法。

例:

关键字=>猫,狗和文本=>一只朗朗上口的猫和一只顽强的狗

现在更改了关键字=>'猫','狗','猫'','狗''(只需附加空格和换行符)

更改的文本=>'一只朗朗上口的猫和一只顽固的狗''

然后,您可以使用标准 Aho-Corasick 算法来查找每个关键字的每个索引。

假设文本长度为 n,总长度关键字为 m,则 Aho-Corasick 算法具有 O(n+m) 复杂度,足以满足大文本和大关键字集的需求。

按单词拆分文本,将所有单词推送到Dictionary<word, index>中,并在每个关键字的字典中查找。

希望下面的函数将返回每个关键字的索引列表。

private List<int> GetIndexForKeyWord(string content,string key)
{
    int index = 0;
    List<int> indexes=new List<int>();
    while (index < content.Length && index >= 0)
    {
        index = content.IndexOf(key, index);
        if (index+key.Length==content.Length||index >= 0 && !char.IsLetter(content[index + key.Length]))
        {
            indexes.Add(index);
        }
        if(index!=-1)
            index++;
    }
    return indexes;
}