2014-02-11 6 views
2

파일 (* .txt)에서 고유 한 문자열을 추출해야합니다. 하지만 내 코드는 같은 줄이 반복되도록 작성되었습니다. 한 번 발행 된 각 고유 문자열을 가져와야합니다.고유 한 문자열 가져 오기 C#

내 코드 :

OpenFileDialog opendialog = new OpenFileDialog(); 
if (opendialog.ShowDialog() == DialogResult.OK) 
{ 
    var lines = File.ReadLines(opendialog.FileName); 
    string pattern = @"set vrouter ""([\w-]+)"""; 
    foreach (var line in lines) 
    { 
    var matches = Regex.Matches(line, pattern); 
    foreach (Match match in matches) 
    { 
     if (match.Success) 
      textBox1.AppendText(match.Value + '\n'); 
    } 
    } 
} 

출력 :

set vrouter R1 
set vrouter R1 
set vrouter R2 
set vrouter R3 
set vrouter R2 
set vrouter R4 
set vrouter R4 
set vrouter R5 
set vrouter R1 
set vrouter R6 
set vrouter R4 
set vrouter R3 
set vrouter R5 

변경된 코드 :

private void button1_Click(object sender, EventArgs e) 
{ 
    OpenFileDialog opendialog = new OpenFileDialog(); 
    if (opendialog.ShowDialog() == DialogResult.OK) 
    { 
    var lines = File.ReadLines(opendialog.FileName); 
    string pattern = @"set vrouter ""([\w-]+)"""; 

    var matches = 
     lines.SelectMany(line=> Regex.Matches(line, pattern) 
      .Cast<Match>()).Where(m => m.Success) 
      .Select(m => m.Value) 
      .Distinct(); 

    foreach (String match in matches) 
    { 
     textBox1.AppendText(match + Environment.NewLine); 
    } 
    } 
} 

그것은 올바른 일 음 !!!

답변

9

정확하게 이해하면 중복을 제외하고 싶습니다. Enumerable.Distinct을 사용할 수 있습니다. 당신은 당신이 ReadLines 때문에 외부 foreach을 사용하려는 경우 File.ReadAllLines 대신 File.ReadLines를 사용할 필요가

주 첫 foreach 열거에 배치됩니다 후드 아래 StreamReader를 사용합니다. 모든 라인에서 고유 일치합니다

var matches = Regex.Matches(line, pattern).Cast<Match>() 
      .Where(m => m.Success) 
      .Select(m => m.Value) 
      .Distinct(); 

foreach (String match in matches) 
    textBox1.AppendText(match + Environment.NewLine); 

이 (여기 당신이 File.ReadLines 함께있을 수 있습니다) : 예를 들어

var matches = lines 
    .SelectMany(line => Regex.Matches(line, pattern).Cast<Match>()) 
    .Where(m => m.Success) 
    .Select(m => m.Value) 
    .Distinct(); 

내 두 번째 방법을 명확히하기 위해, 이것은 어떤 외부의 foreach에서 필요하지 않습니다 모두 SelectMany은 이미 모든 행의 모든 ​​일치 항목을 선택하여 대체합니다. 결과를 출력하려면 foreach 중 하나만 필요합니다.

+0

귀하의 발언에 따라 코드가 변경되었습니다. 나는 그것을 여기에 추가했다. 하지만 나는 오류가 있습니다. 어쩌면 내가 어딘가에 오류가 있었습니까 ?? – user3214034

+0

@ user3214034 : 문제가 무엇인지 보겠습니다. 'File.ReadLines'는 내부적으로'StreamReader'를 사용합니다. 이는 내부 'foreach'에서 발생하는 (LINQ-) 쿼리를 실행하자 마자 처리됩니다. 따라서 ** 모든 행 **에서 고유 한 일치 항목을 반환하는 두 번째 방법을 사용해야합니다 (처음 사용한 방법과 반대). 또는 먼저 모든 라인을 메모리 ('string []')에 읽어들이는'File.ReadAllLines'을 사용해야합니다. 'SelectMany'는 이미 모든 라인의 모든 일치를 선택했기 때문에 나의 두 번째 접근법은 바깥 쪽 foreach를 필요로하지 않습니다. –

+0

죄송합니다! 이전 코멘트는 불공평했습니다! 훌륭하게 작동했습니다 !!! 고맙습니다!!! – user3214034

관련 문제