2014-03-26 43 views
2

在我正在處理的應用程序中,我創建了關鍵字搜索器。用戶上傳一個文本文件(因爲這是爲了工作,它將是一個包含數千行消息的txt文件),並且可以輸入多個單詞來搜索,並且應用程序用相應的輸入抽出任何行。唯一的問題是,他們希望能夠在被複制的行的上面和下面拉出n行,以便他們可以看到被拖動的消息的上下文。有沒有辦法說,複製這一行和n以上和以下的行數?以下是我的代碼,用於搜索單詞並編寫它。在C#中的文本文件後面添加行的上方和下方寫入n行代碼

private void button12_Click(object sender, EventArgs e) 
{ 
    string[] sArray = System.IO.File.ReadAllLines(textBox7.Text); 
    StringBuilder sb = new StringBuilder(); 

    foreach (string line in sArray) 
    { 
      if (Regex.IsMatch(line, (textBox9.Text), RegexOptions.IgnoreCase) && !string.IsNullOrWhiteSpace(textBox9.Text)) 
      { 
       sb.AppendLine(line); 
      } 

      if (Regex.IsMatch(line, (textBox10.Text), RegexOptions.IgnoreCase) && !string.IsNullOrWhiteSpace(textBox10.Text)) 
      { 
       sb.AppendLine(line); 
      } 
     } 

     using (StreamWriter sw = new StreamWriter(textBox8.Text)) 
     { 
      sw.Write(sb); 
     } 
    } 
} 
+0

所以你想構建grep,對吧?我會使用'for'而不是'foreach'。通過這種方式,你有可能「知道」一個匹配的行號並做你想做的任何事情;-) –

+0

嗯不知道什麼是grep,謹慎解釋? – KP123

+0

我已經發布了一個小例子,你可以實現它。您必須每個單詞調用一次該方法。 –

回答

2

我提供了一個小例子。您可以使用它像這樣:

List<string> lines = new List<string>() {"This", "is", "some", "test", "data"}; 
List<string> result = GetMatchingLines(lines, "test", 2, 2); 

的方法是這樣的:

/// <summary> 
/// Gets all lines containing the "match" including "before" lines before and "after" lines after. 
/// </summary> 
/// <param name="lines">The original lines.</param> 
/// <param name="match">The match that shall be found.</param> 
/// <param name="before">The number of lines before the occurence.</param> 
/// <param name="after">The number of lines after the occurence.</param> 
/// <returns>All lines containing the "match" including "before" lines before and "after" lines after.</returns> 
private List<string> GetMatchingLines(List<string> lines, string match, int before = 0, int after = 0) 
{ 
    List<string> result = new List<string>(); 

    for (int i = 0; i < lines.Count; i++) 
    { 
     if (string.IsNullOrEmpty(lines[i])) 
     { 
      continue; 
     } 

     if (Regex.IsMatch(lines[i], match, RegexOptions.IgnoreCase)) 
     { 
      for (int j = i - before; j < i + after; j++) 
      { 
       if (j >= 0 && j < lines.Count) 
       { 
        result.Add(lines[j]); 
       } 
      } 
     } 
    } 

    return result; 
} 

以你的代碼考慮方法將在某種程度上可以這樣調用:

string[] lines = File.ReadAllLines(textBox7.Text); 
List<string> result = new List<string>(); 

if (!string.IsNullOrEmpty(textBox9.Text)) 
{ 
    result.AddRange(GetMatchingLines(lines.ToList(), textBox9.Text, 2, 2)); 
} 

if (!string.IsNullOrEmpty(textBox10.Text)) 
{ 
    result.AddRange(GetMatchingLines(lines.ToList(), textBox10.Text, 2, 2)); 
} 

File.WriteAllLines(textBox8.Text, result); 
+0

你發佈的兩個方法都是同一個東西只是一個是我的代碼?他們爲什麼看起來如此不同? – KP123

+0

最後一個顯示瞭如何使用我在示例代碼的上下文中編寫的方法;-)因此,您可以在button_click事件中編寫最後一個代碼。 –

+0

酷,所以我可以把最後一個片段放在我的按鈕中,它應該工作?當我放入時,GetMatchingLines出現錯誤?我添加了第一個按鈕單擊之前發佈的方法,然後將第二個方法添加到按鈕處理程序中。那是對的嗎? – KP123

0

既然你正在尋找不同的線路與行之間的整數差,你可能要編輯您的foreachfor代替。

這將允許你說這樣的話

var thisLine = sArray[i]; 
var oneLineBefore = sArray[i-1]; 
var oneLineAfter = sArray[i+1]; 
sb.Append(oneLineBefore); 
sb.Append(thisLine); 
sb.Append(oneLineAfter); 

顯然,要確保你檢查,以確保訪問它們之前的之前和之後的行存在。

相關問題