2013-08-21 2 views
3

RegEx 패턴이있는 지침이 필요합니다.C# RegEx가 파이프로 구분 된 파일에서 빈 셀을 찾습니다.

나는 네 번째 셀이 비어있는 모든 줄을 제거하려고하는 파이프 구분 파일이 있습니다. 각 행에는 셀 수에 제한이 없습니다. 지금까지

내 코드 :

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Text.RegularExpressions; 
using System.Threading.Tasks; 

namespace EpicRemoveBlankPriceRecords 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string line; 

      // Read the file and display it line by line. 
      System.IO.StreamReader inFile = new System.IO.StreamReader("c:\\test\\test.txt"); 
      System.IO.StreamWriter outFile = new System.IO.StreamWriter("c:\\test\\test_out.txt"); 
      while ((line = inFile.ReadLine()) != null) 
      { 
       Match myMatch = Regex.Match(line, @".*\|.*\|.*\|\|.*"); 
       if (!myMatch.Success) 
       { 
        outFile.WriteLine(line); 
       } 
      } 

      inFile.Close(); 
      outFile.Close(); 

      //// Suspend the screen. 
      //Console.ReadLine(); 


     } 
    } 
} 

이 작동하지 않습니다. RegEx가 "탐욕 스럽다"고 생각하기 때문에 - "파이프 문자를 제외한 모든 것을 잡아라"라고 명시 적으로 말하지 않았기 때문에 공백 셀이 있으면 일치합니다. 빠른 google과 나는 패턴에서 [^ \ |]을 사용하여 그것을 할 수 있음을 알았다.

그래서,에 패턴을 변경하는 경우 :하지 않는 이유는이 작품 중 하나

".*[^\|]\|.*[^\|]\|.*[^\|]\|\|.*" 

?

내가 약간 혼란 스럽다는 것을 짐작할 수 있습니다.

감사합니다.

+0

너는 나에게 너무 빨랐다. 나는 그것을 알아 차리고 그에 따라 편집했다. 불행히도 내 패턴은 여전히 ​​작동하지 않습니다. 감사합니다. – Ekins86

+2

정규 표현식을 사용해야하는 이유가 있습니까? 나에게'string.IsNullOrEmpty (line.Split ('|') [2])와 같은 것을하는 것이 훨씬 쉽습니다. –

+0

1에서 1 번째 또는 0에서 3 번째 항목? =) – Maslow

답변

1

:

^[^|]*\|[^|]*\|[^|]*\|\|.* 
혼자
  • ^| 제외 라인
  • [^|] 모든 문자의 시작
  • [^|]* 일치하는 0 개 이상의 비 | 문자를 의미
  • + 할 수있다 너의 사용법에 대해 틀리나. 적어도 하나 이상을 의미하지만 더 많이 발견 할 수 있습니다.
  • .*은 무엇이든 찾을 수있는 모든 것을 의미합니다.

테스트 데이터 :

  • ABC | 123 | || 673
  • ABC 234 | DEF 123 || | 456
  • ABC | 123 | 234 | 673 || AB
+0

nm, 질문이 누락되었습니다 – Maslow

+0

샘플 데이터 및 강조 표시가있는 제안 된 솔루션 - http://j.mp/14CryLM – Maslow

+0

죄송합니다. 다시 말하지만, 파일의 뒷 부분에서 공백 필드를 찾습니다. 나는 abc를 잡는다. | 123 | 234 | 673 || ab || – Ekins86

1

.*[^\|]는 0 개 이상의 와일드 카드 (.*)와 | ([^\|]) 아닌 하나 개의 문자를 의미합니다.

또한 | 번을 [] 번으로 이스케이프 처리해야합니다.

그리고 Regex.Match은 실제로 일치하지 않으므로 정규식의 시작 부분에 ^ (문자열의 시작을 나타냄)이 필요합니다.

그리고 꼬리말 .*도 필요하지 않습니다.

"^[^|]*\|[^|]*\|[^|]*\|\|" 

Test :

는 대신이 같은 |하지 않은 0 개 이상의 문자를합니다.

".*\|.*\|.*\|\|.*"이 작동하지 않은 이유 : 위의 이유에서 그렇다

...

*을 정말 많이 변경되지 않습니다 욕심 (당신은/비 욕심 수행하여 게으른 할 수 있습니다 .*?). 문제는 .|과 일치하여 다시 추적하므로 |이 문자열과 일치하는 데 필요한만큼 많거나 적은 수를 포함합니다 (예, 욕심 때문에 더 많이 포함하려고 시도하지만 이는 그렇지 않습니다). 뭔가를 찾았는지 찾지 만, 발견 한 것만 변경하십시오).

게으른 일치 및 possessive quantifiers을 사용하여 무언가를 함께 해킹 할 수는 있지만 다소 복잡해지고 더 중요한 것은 C#이 그러한 것을 지원하지 않는다고 가정합니다.

regexpal에서 작업 표시
+0

이것은 공백이 있으면 여전히 잡을 것 같습니다 (예 : 5 번째 셀이 비어있는 경우 2, 3, 4, 5 셀을 잡는다.) – Ekins86

+0

@ Ekins86 이것은 작동 할 것이다. 단지'^'와'$'를 시작과 끝 부분에 추가하면된다. 정규식. –

+0

@ Ekins86 'Match'가 일치하지 않는 것 같습니다. 내 대답을 조금 편집했습니다. – Dukeling

2

정말 정규식이 필요합니까?

var lines = File.ReadLines(filename) 
      .Where(line => !String.IsNullOrWhiteSpace(line.Split('|')[3])); 

File.WriteAllLines(outfile, lines); 
+0

+1이이 정규 표현식보다 훨씬 낫다. – Maslow

관련 문제