2014-03-26 1 views
2

제가 연구중인 응용 프로그램에서 키워드 검색기를 만들었습니다. 사용자는 텍스트 파일을 업로드합니다 (작업을위한 것이므로 수천 줄의 메시지가있는 txt 파일이 될 것입니다). 검색을 위해 여러 단어를 입력 할 수 있으며 응용 프로그램은 해당 입력이있는 모든 행을 가져옵니다. 유일한 문제는 복사중인 행의 위와 아래에있는 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을 만들고 싶습니다. 그렇습니까? 나는 foreach 대신에 for를 사용할 것이다. 이 방법으로 일치의 행 번호를 "알거나"원하는대로 할 수 있습니다. –

+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 A를 편집 할 수 있습니다.

이것은 당신이 당신이 그들에 액세스하기 전에 선 전후가 존재하는지 확인하려면 않습니다 확인, 분명히

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

같은 말을 할 수있다.

관련 문제