在完全匹配 C# 的文本中查找所有关键字及其索引
本文关键字:查找 关键字 索引 文本 | 更新日期: 2023-09-27 18:36:38
我有一个关键字列表和一个文本来搜索它们。我需要获取文本中每个找到的关键字的开始索引,并且匹配必须准确。例如:
keywords=>cat,dog
text=> a catchy cat with a dogged dog
在这里,虽然只匹配"猫"和"狗",但必须返回与索引的匹配,并且不应使用"朗朗上口"和"顽固"之类的词进行匹配
我已经尝试过 Aho-Corasick 算法进行字符串匹配,但它也匹配"朗朗上口"和"顽固"。如何使用 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;
}