2012-02-11 2 views
3

저는 텍스트 파일을 파싱하는 프로젝트를 진행하고 있습니다. 파일이 네트워킹 장비에서 출력됩니다. 들어오는 문자열은 수천에서 수만 줄에 이릅니다. 다음과 같은 키워드가 포함 된 다양한 항목이 있습니다.문자열 구문 분석 - 각 행을 확인하는 것보다 효율적인 방법이 있습니까?

fcN/N is up 
    Hardware is Fibre Channel, SFP is short wave laser w/o OFC (SN) 
    Port WWN is 20:52:00:0d:ec:ef:b0:40 
    Admin port mode is F, trunk mode is on 
    snmp link state traps are enabled 
    Port vsan is 10 

fcipN is up 
..... 

port-channel-N is trunking 
...... 

N은 숫자입니다. 'fcN/N'항목이 항상있을 것이며 다른 두 항목이있을 수도 있고 없을 수도 있습니다. 'fcip'및 'port-channel'항목은 각각의 fcN/N 항목 뒤에 유사한 상태 정보를 갖습니다. 동일한 유형의 모든 항목이 그룹화됩니다. fc 다음에 fcip이 나오고 다른 fc가옵니다. 또한 일반적으로 모든 fc 항목이 나열된 다음 모든 포트 - 채널 다음 모든 fcip하지만 나는 그것을 가정하고 싶지 않습니다. 현재 나는 약 7 가지 RegEx 패턴을 찾고 있습니다. 차례대로 각 라인을 검사하여이 작업을 수행하지만, 모든 작업을 관리하는 것은 번거로운 작업입니다. 나는 줄 바꿈에 문자열을 분할하고 LINQ를 선택하여 3 가지 유형의 항목을 모두 얻으려고 생각했지만, 항상 같은 순서로 그룹화된다고 가정합니다. 나는 또한 한 항목에서 다음 항목까지 모든 것을 일치시키는 약 3 개의 괴물 정규식을 생각했지만, 내 경험에 의하면 작업하기가 어렵고 거의 읽을 수 없다. 내가 생각한 또 다른 사항은 fc 나 port-channel 또는 fcip과 같은 3 개의 키워드를 먼저 찾은 다음 해당 키워드에 고유 한 패턴과 일치하는 if 문을 사용하는 것입니다. 그것은 여전히 ​​모든 3 패턴에 대한 각 라인을 일치합니다.

명확하게 말하면 정규 표현식 패턴이 작동합니다. 나는 6 0r 8 경기에 대한 각 라인을 테스트하는 것보다 더 효율적인 방법을 찾고있다.

다른 아이디어?

+4

지금 성능 문제가 있습니까? Regex가 컴파일되어 있습니까? – Damien

+0

아니요. 나는 단지 무자비한 포스보다 더 우아한 방법을 찾고 있습니다. 더 우아한 방법이 없을지도 모릅니다. 그리고 나는 그것으로 차갑습니다. :) 나는 당신이 정규식을 컴파일 할 수 있는지, 그것이 무엇을 의미하는지 확신하지 못했습니다. –

답변

0

내가이 생각을 가지고

(1) 문을 처음 적용 할 수있는 권리 정규식을 찾을 경우 사용하는 당신의 마지막 접근 매우 효율적으로 같다. 나는 그것을 권하고 싶다. 이 같은

(2)가 구성 할 수 정규식의 : 이것은 훨씬 더 쉽게 읽을

var pattern1 = @"abc"; 
var pattern2 = @"def"; 
var unionPattern = "((" + pattern1 + ")|(" + pattern2 + "))"; 

.

줄을 넘는 일치 항목을 찾고 싶지 않으면 파일을 먼저 줄로 나누어야합니다. regexes는 입력이 적기 때문에 효율성을 향상시킬 수 있습니다. 당신의 일치가 여러 줄에 걸쳐 있지만, 항상 새로운 줄 끝에서 시작하는 경우

, 당신은 다음과 같이 첫 번째 조각으로 문자열을 분할 할 수 있습니다 :

var chunks = Regex.Split(str, "((fc\d)|(fcip\d)|(port-channel-\d))); 
+0

죄송합니다. 분명치 않았습니다. 입력 문자열에 이미 행이 있습니다. 그것은 StringReader를 선언하고 각 행을 읽도록합니다. ReadLine()과 동일한 문자열을 설정 한 다음 문자열에서 모든 일치 항목을 검색합니다. –

+0

내가 할 일은 내가 주 파일에 사용하는 것과 비슷한 접근법이라고 생각한다. 나는 키워드를 찾을 것이다. 내가 찾으면 다음 키워드를 읽고 방금받은 덩어리를 처리합니다. 그런 식으로 각 패턴마다 모든 단일 라인을 검사하지는 않습니다. 나는 3 개의 주요한 성냥에서 시작하고, 그 때 나가 찾아내는 무슨을에 따라 다른 사람을 이용한다. –

0

당신은 사용하여 선명하고 더 간결한 코드를 얻을 수 있습니다 파서 결합 자 라이브러리 (예 : Sprache)

C# 프로그래머가 아니기 때문에이 라이브러리에 친숙하지 않습니다. (물론 C#에서도 다른 것들이있을 수 있습니다.)하지만 스칼라 파서 결합기를 사용하여 효과를 얻었습니다. 정규식 파싱.

코드를보다 효율적으로 만들 수 있는지 여부는 현재 코드가 얼마나 비효율적인지에 따라 다릅니다.

0

원시 속도 또는 효율을 찾고 계십니까? 전자의 경우 파일을 여러 부분으로 나누고 각 부분을 동시에 파싱 할 수 있습니다. 그 트릭은 각 부분이 전체 항목 만 포함하도록 분할 할 경계를 찾는 것입니다.전체 라인 수가 많거나 오버 헤드가 병렬화 이득보다 클 경우 멀티 스레드로 전환하기를 원할 것입니다.

+0

나는 능률 및/또는 내가 가진 것보다 더 우아한 것을 찾고있다. 속도 문제가 없습니다. 전체 파일의 평균 크기는 30MB입니다. 나는 그것의 여러 부분을 검색하고 전체 것은 몇 초 안에 완료됩니다. 내가하는 일은 파일에서 명령을 검색하고, 다음 명령을 누를 때까지 각 행을 문자열로 읽는 것입니다. 그런 다음 해당 문자열을 파서의 특정 부분을 구문 분석하는 파서에 전달합니다. 내가 요구하는이 섹션에서는 찾는 패턴이 많이 발생합니다. 나는 그것을하는 더 빠른 방법이 있는지 궁금해했다. –