2013-10-24 40 views
3

我有一个关键字列表和一个文本来搜索它们。我需要在文本中获取每个找到的关键字的起始索引,并且匹配必须准确。例如:查找所有关键字及其索引中的文本完全匹配c#

keywords=>cat,dog 
text=> a catchy cat with a dogged dog 

这里同时匹配只有“猫”和“狗”匹配指数必须返回比赛不应该是与像

我已经试过Aho-Corasick Algorithm for string matching“上口”和“顽强”的话但它也符合'吸引人的'和'顽固的'。我怎样做的关键字精确匹配,并使用C#

+0

这是一次性搜索,还是多个?如果多个文字或关键字不断变化? –

回答

3

与边界使用正则表达式返回文本中的索引位置..

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

现在,您可以遍历导致

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

是对大文本和10K关键字有效的Linq方法吗? – jeff

+0

@jeff ahh..yes性能将是一个问题,但它不是特定于LINQ ..匹配一个100MB的文本文件中的10k关键字肯定需要时间!我会使用线程或任务异步运行而不会阻塞.. – Anirudha

+0

我会试试看,并提出反馈意见。BTW – jeff

0

你可以用Aho-Corasick算法做一些修改。 对于所有关键字,在每个关键字的末尾添加字词分隔符(如空格,点,换行符等)。

所以,如果你有m个关键字,并且文本有n种类型的分隔符,你将从n * m个单词构建树状结构树。

追加分隔符后,它不会匹配示例中的'catchy'和'dogged'。

编辑:

首先你最好有一个AC算法的理解。

例子:

关键字=>猫,狗和文本=>一个引人注目的猫用顽强的狗

现在改变关键字=> '猫', '狗', '猫\ n', “狗\ N”(只是追加空间和换行分隔符)

改变文本=>“一个引人注目的猫用顽强的狗\ n”

然后你可以使用standord阿霍Corasick算法串找到每个每个关键字的索引。

假设文本的长度是n,并且总长度关键字是m,则Aho-Corasick算法具有O(n + m)复杂度,足以用于大文本和大关键字集合。

+0

你可以用一个例子来阐述一下。 – jeff

0

Hope下面的函数会返回每个关键字的索引列表。用语言

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; 
} 
+0

IndexOutOfRange为文本中的最后一个关键字。 –

+0

@Толя:谢谢你指出。更改了代码。 – Santhanam

0

拆分文本,推动所有单词到Dictionary<word, index>和查找到字典中为每个关键字。

相关问题