2016-10-26 2 views
0

기본적으로 거대한 클래스 세트 (참조 용 C#) 인 제 3 자의 파일이 제공되는 성가신 문제가 있습니다. 지금은이 클래스의 여러 개정판을 보유하고 있으며 일부 알려지지 않은 이유로 제 3 자 개발자가 파일을 수정하여 개정판으로 옮깁니다. 따라서 이전 버전의 변경 사항에 문제가 있고 시간이 오래 걸릴 수 있습니다.텍스트 분석/정규식을 사용하여 큰 텍스트 파일을 여러 개의 작은 파일로 분할

public class Abc 
{ 
    ... 
} 

public class Xyz 
{ 
    ... 
} 

따라서, 나는 (그 클래스의 이름을 따서 명명, 예를 들어 Abc.cs, Xyz.cs 등) 여러 파일에 자신의 전달 파일을 분할 할 수 있도록하고 싶습니다. 몇 가지 파일을 추가하겠습니다 만, 적어도 제공된 파일에서 동일한 스크립트를 실행할 수 있고 생성 된 파일에 diff를 수행하여 해당 특정 클래스의 수정본을 판별 할 수 있으므로 변경 사항을 쉽게 볼 수 있습니다 .

나는 Powershell과 Regex의 경험이 모두 있는데, PS에서 가능할 것이라고 생각했지만 솔직히 머리가 벽돌 벽에 부딪쳤다. 내 다소 절름발이 시도에서, 나는 그 파일에서 각각의 닫는 클래스 대괄호 (})를 추출 할 수 있었다. 나는 또한 "\r\npublic class ""\r\n}" (\r\npublic class(.*)\r\n}\r\n) 사이의 모든 정규식을 시도했지만이 중 첫 번째 클래스 만 출력되거나 전체 파일이 이동되거나 전혀 작동하지 않게됩니다. 이것은 분명히 내가 public class의 인스턴스를 반복하지 않는다는 것을 보여 주지만 나의 예제는 멀티 라인 솔루션보다는 CSV를 분리하는 데 더 적합한 솔루션과 매우 흡사합니다.

모든 경우에 public class 선언 및 닫기 괄호가 새 줄에 있으므로이 부분이 튀어 나오는 가장자리가 없어야합니다. 파일은 특별히 크지 않으며 (< 2MB), Get-Content을 통해 읽는 시간은 전혀 없습니다. 나의 초기 연구는 내가 StreamReader을 사용할 것을 제안했지만, 그것은 나의 유스 케이스에 대해 불필요한 잔인 함이다.

올바른 방향으로 어떤 포인터가 크게 여기에 감사하겠습니다. 사전에

많은 감사

+1

이것은 [Roslyn] (https://github.com/dotnet/roslyn)의 일일 것입니다. – IInspectable

답변

1

분할 :

(Get-Content r:\1.cs | Out-String) -split '(?:^|\r\n)public class\s+' -ne '' | 
    ForEach { 
     $className = $_ -replace '(?s)^(\w+).*$', '$1' 
     "public class $_" | Out-File "r:\$className.cs" -encoding UTF8 
    } 

비틀기 : PS3.0에서

가 + : 어떤 PS에서 (Get-Content r:\1.cs -raw) 대신 (Get-Content r:\1.cs | Out-String)
를 사용 [IO.File]::ReadAllText('r:\1.cs')도 빠릅니다.

+0

고맙습니다! 나는'public class'에 의해서만 분할하는 것을 고려해 보았습니다 만, 이전 줄에서'[Serialization]'과 같은 클래스 속성을 잃어 버렸습니다. 그러나, 나는 당신이 제공 한 것으로 처리 할 수 ​​있습니다. 다시 감사합니다! –

1

다음은 공공의 클래스를 추출 할 가정 당신을 위해 작동 할 수 있습니다 내가 함께 던졌다 뭔가입니다 : https://regex101.com/r/urLWuz/2

(public\s*class\s*(\S*)\s*\{.*?(?:\}(?=\s*(?:(?:public\s*class)|$)))) 
  • (을 - 캡처 그룹을 시작은 전체 클래스를 포함하는 클래스

    • public\s*class\s*(\S*) - 클래스 선언을 일치시키고 이름을 캡처하십시오. 제품 내부의 게으른 경기 - 클래스의 내용
    • .*?의 경기가 시작 중괄호 - \s\S는 공백이 아닌
    • \s*\{ 일치합니다, 공백을 일치합니다. 대신 욕심이 많은 경우 모든 클래스가 하나의 일치로 일치합니다.
    • (?:\}(?=\s*(?:(?:public\s*class)|$))) - 닫는 중괄호 다음에 무엇을 선택 공백 중 하나를 다른 클래스 뒤에 주장 긍정적 인 내다보기를 사용하여 닫는 중괄호 일치 - 비 캡처 그룹
      • \}(?=\s*(?:(?:public\s*class)|$))를 사용하여 클래스의 내용이 끝나는 중괄호 일치 , 또는 파일의 끝. 파일 가능성의 끝을 고려하지 않으면 마지막 클래스는 캡처되지 않습니다.비 캡처 그룹은 캡처와 그룹화에 사용됩니다.
    • )

  • -이 각 클래스뿐만 아니라 클래스 이름을 캡처해야

전체 일치 클래스의 캡처 그룹을 닫습니다. 기본적으로 중괄호 뒤에 오는 클래스 선언 또는 파일의 끝을 확인하여 클래스의 닫는 중괄호를 확인합니다.

모든 클래스가 네임 스페이스 내에있는 경우 약간 수정해야합니다. 라인 시작에 public class에 의해

+0

감사합니다. 궁극적으로 나는 이것을 사용하지 않았지만, 이전에 regex101.com을 인식하지 못해서, 현재 사용중인 go-to regex 도구 인 Regex Coach가 언제나 훌륭하지는 않습니다. –

관련 문제