2014-01-30 5 views
1

다음은 텍스트 파일에서 읽는 방법입니다. 읽는 동안 주어진 문자열에 정규 표현식을 매치 할 필요가 있습니다. 일치하면 라인 문자열을 컬렉션에 추가해야합니다. 이 방법은 28,653 라인을 가진 4MB의 텍스트 파일을 실행Regex를 사용하여 텍스트 파일에서 읽기

private static void GetOrigionalRGBColours(string txtFile) 
{ 
    string tempLineValue; 
    Regex regex = new Regex(@"^\d+.?\d* \d+.?\d* \d+.?\d* SRGB$"); 

    using (StreamReader inputReader = new StreamReader(txtFile)) 
    { 
     while (null != (tempLineValue = inputReader.ReadLine()))      
     { 
      if (regex.Match(tempLineValue).Success 
       && tempLineValue != "1 1 1 SRGB" 
       && tempLineValue != "0 0 0 SRGB") 
      { 
       string[] rgbArray = tempLineValue.Split(' '); 
       RGBColour rgbColour = new RGBColour() { Red = Convert.ToDecimal(rgbArray[0]), Green = Convert.ToDecimal(rgbArray[1]), Blue = Convert.ToDecimal(rgbArray[2]) }; 
       originalColourList.Add(rgbColour); 
      } 
     } 
    } 
} 

, 그냥 위의 방법을 완료 주변 삼분 소요됩니다. 또한 위 실행 결과로 originalColourList에는 582 개의 항목이 채워집니다.

아무에게도이 방법의 성능을 어떻게 향상시킬 수 있습니까? 실제 텍스트 파일 크기는 60MB까지 올 수 있습니다. 정규식에 대한

FYI-
마우스 오른쪽 버튼으로 경기 : 정규식에 대한 0.922 0.833 0.855 SRGB
잘못된 경기 :/SRGB/setrgbcolor 여기서 부하 데프
txt 파일은 원래 포스트 스크립트 파일이, 내가 저장 한되어 그 조작을위한 TXT 파일로 C#을 사용합니다.

+0

정규 표현식에서 옳고 그른 부분을 표시하면 더 좋은 답변을 얻을 수 있습니다.이것은 정규 표현식이 실제로 필요한지 여부를 결정하는 데 도움이 될 수 있습니다. –

+0

자세한 내용을 포함하도록 수정되었습니다. – iniki

답변

3

정규식 당신이 이런 식으로 다시 작성하면 훨씬 더 빨리, 많이있을 것입니다 :

Regex regex = new Regex(@"^\d+(\.\d*)? \d+(\.\d*)? \d+(\.\d*)? SRGB$"); 

주 두 가지 중요한 변화 : 정규식이 일치하도록

  1. . 백 슬래시로 이스케이프 문자 대신 문자 그대로의 점.
  2. \.과 그 다음은 \d*은 그룹으로 선택 사항이며, \.은 선택 사항입니다. \d+.?\d*quantifiers (+, ?*) 연속 포함하고 있기 때문에

원래 정규식가 느립니다. 이로 인해 정규 표현식 엔진이 긴 숫자 시퀀스로 시작하는 줄을 일치 시키려고 할 때 과도한 이 발생합니다. 예를 들어 내 컴퓨터에서 10,000 개의 0이 포함 된 줄은 4 초보다 길게 일치합니다. 수정 된 정규식은 4 밀리 초 미만인 (1000x 개선)을 사용합니다.

정규식을 사용하면 Regex 생성자에 두 번째 인수로

RegexOptions.Compiled | RegexOptions.ECMAScript 

를 전달하면 더 빨리 (머리가) 될 수 있습니다. ECMAScript\d[0-9]으로 처리하고, 신경 쓰지 않는 7 (티벳 7)과 같은 유니 코드 숫자를 무시하도록 정규식 엔진에 지시합니다.

+0

아주 좋은 설명 마이클. – Kevin

0

레코드 형식에 따라 정규식을 사용하는 것보다 빠르게 구문 분석 할 수 있습니다. 파일에 대한 모든 것을 알지는 못했지만, 두 가지 예제를 통해 최적화 된 정규 표현식을 사용하는 것보다 약 30 % 빠릅니다.

 decimal r; 
     decimal g; 
     decimal b; 
     string rec; 
     string[] fields; 
     List<RGBColour> originalColourList = new List<RGBColour>(); 

     using (StreamReader sr = new StreamReader(@"c:\temp\rgb.txt")) 
     { 
      while (null != (rec = sr.ReadLine())) 
      { 
       if (rec.EndsWith("SRGB")) 
       { 
        fields = rec.Split(' '); 

        if (fields.Length == 4 
         && decimal.TryParse(fields[0], out r) 
         && decimal.TryParse(fields[1], out g) 
         && decimal.TryParse(fields[2], out b) 
         && (r+g+b !=0) 
         && (r != 1 && g != 1 && b!=1) 
         ) 
        { 
         RGBColour rgbColour = new RGBColour() { Red = r, Green = g, Blue = b }; 
         originalColourList.Add(rgbColour); 
        } 
       } 
      } 
     } 

if는 조건이 거짓 일 때 단락하고 모든 것이 true이면 더 이상 모든 값을 10 진수로 변환 할 필요가 없습니다. 약 12.5 초 만에 600 만 줄을 파싱했습니다.