2013-10-24 39 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>和查找到字典中爲每個關鍵字。

相關問題