2010-02-16 4 views
0

나는 Hyperic HQ에 의해 생성 된 경고에서 정보를 구문 분석 할 일부 정규식을 작성하려고합니다. 경고는 같은 제목과 함께 이메일로 제공 :어설 션 및 옵션 부분 문자열 뒤에서의 문제

"[HQ] !!! - Alert: My Demo Website Alert Resource: demo.myserver.net Apache Web Server State: fixed" 

짧은 매우 긴 이야기를 잘라, 나는 일관되게 상관없이 호스트 이름은 "아파치 웹 서버"부분을 잡아 할 수 있어야하는하지 않을 수 있습니다 심지어 존재할 수도있다. 나는 호스트 이름이 항상 "myserver.net"을 끝낼 것임을 알고 있습니다.

내가 가진 정규식은 다음과 같습니다이 선택적으로 호스트 이름을 다음과 같은 (그러나 포함하지 않음), "Resource:""State:" 사이에 0 개 이상의 문자와 일치합니다 내가 기대했다

/Resource:\s.*(?<=mydomain.net)?\s(.*)\s(?=State)/ 

있다.

반환 값은 일치하는 비트의 마지막 단어 인 "Server"입니다. 이것은 호스트 이름이 문자열에 있는지 여부에 관계없이 발생합니다.

아무도 도와 줄 수 있습니까?

편집 : 이것은 내가

/Resource:\s(?:.*myserver.net)?(?<PartIWant>.*)\s(?:State)/ 

당신의 정규식 엔진 경우 명명 된 캡처 그룹 "PartIWant"에있을 것입니다 쓴 테스트 작업을 나타납니다

/Resource:\s(?:.*.myserver.net)?(.*)\sState/ 

답변

2

아래 차드가 제공하는 솔루션 명명 된 캡처 그룹을 지원합니다.

편집 : 나는이 내가 Lookaround-조기 상환 청구 전화 안티 패턴의 예입니다

[HQ] !!! - Alert: My Demo Website Alert Resource: demo.myserver.net Apache Web Server State: fixed 
[HQ] !!! - Alert: My Demo Website Alert Resource: Apache Web Server State: fixed 
+0

다운로드 프레소에서, 테스트 데이터에서 모든 가능한 문자열을두고,이를 실행하고 제대로 – CaffGeek

+0

1 일치하는 경우를 참조하십시오. "State"에 대한 미리보기를 사용하지 않아도됩니다. –

+0

@Alan, 알기조차하지 않았다, 맞다, 거기에있을 필요가 없다 – CaffGeek

2

이러한 문자열 모두이 정규 표현식을 테스트했습니다. 당신은 당신이 foo 앞에와 bar 뒤에 찾고있는 문자열을 알고, 당신은 정규 표현식에이 lookbehinds 및 lookaheads라는 것을 알고, 그래서 그 사용한다 무엇 분명한 것 같다 :

(?<=foo).*(?=bar) 

명백한을 조심; regexes에 관해서는 거의 직관적이지 않습니다. 미리보기는 정규 표현식에 상당히 늦은 시각이었으며 나중에조차도 눈에 잘 띄지는 않았지만 사람들은 그들이 오기 전에 오랫동안 이런 종류의 문제를 해결하고 있었다는 것을 기억하십시오. 그들은 캡처 그룹을 사용하여 그것을했다, 그것은 여전히 ​​대부분의 경우 최선의 선택입니다 : 당신의 정규식에 명백한 오류가있다

foo(.*)bar 

입니다 :

(?<=mydomain.net)? 

EditPadPro의 검색하십시오 lookbehind에 ? 정량 상자는 PHP와 마찬가지로 오류로 표시합니다. Java와 .NET은 그렇지 않지만, 나는 그들이해야한다고 믿는다. \b* 또는 ^+ 또는 ${3,7}보다 의미가 없습니다. 그것들은 모두 제로 너비 어설 션입니다. 즉, 아무 것도 일치하지 않는다는 것을 의미합니다. 따라서 한정어를 추가하면 동일한 내용을 여러 번 일치 시키려고합니다 ($은 개행과 일치하지 않으며, 사이의 위치는). 선행 문자).

무한 루프에서 멈출 위험이 없지만 정규 표현식 작성자가 오타를 만들었거나 뭔가 오해를했음을 나타내는 좋은 징후입니다. 한정 기호가 ? 또는 *과 같이 0 번 일치 할 수있는 경우 특히 그렇습니다. 이것은 어설 션을 선택 사항으로 만들고 선택적 어설 션은 관련없는 어설 션입니다. 귀하의 정규식에서 (?<=mydomain.net)?은 "현재 위치가 mydomain.net 앞에 오거나 그렇지 않은 경우 어느 쪽이든 상관 없습니다"를 의미합니다.

어쨌든, 차드는 이미 작동하는 정규식을 생각해 냈습니다. 나는 당신이 왜 그렇게하지 않았는지에 대한 통찰력을 제공하기를 원했습니다. 물론 필자의 반 패턴을 현장 테스트 해보십시오. ;)

+0

그건 내가 제시하고있는 문제가 아닙니다. "foo"와 "bar"로 시작하는 문자열을 찾고 "japh"다음에 "bar"가 나타나거나 나타나지 않을 수도 있지만 * 존재하면 * 싶지 않습니다. 캡쳐해라. –

+1

"foo"와 "bar"에 의해'Resource :'와 호스트 이름 그리고 "japh",'State :'를 의미한다고 가정합니다; 그건 중요하지 않아. 요점은 당신이 그런 것들 중 어느 것과도 일치하도록 둘러보기가 필요 없다는 것입니다; 그냥 "똑바로"일치시키고 캡처 그룹을 사용하여 관심있는 부분을 추출하십시오. 캡처 그룹을 사용하도록 허용되지 않은 경우 좀 더 창의적으로 접근해야하지만 다행스럽게도 그렇지 않습니다. –

1

간혹 사물을 간단하게 처리 할 수 ​​있습니다. 가장 좋아하는 언어로 "myserver.net"을 분할 한 다음 첫 번째 요소의 "State :"를 분할하십시오. 예를 들어 파이썬

>>> s="""[HQ] !!! - Alert: My Demo Website Alert Resource: demo.myserver.net Apache Web Server State: fixed""" 
>>> s.split("myserver.net")[-1].split("State:")[0] 
' Apache Web Server ' 
+0

아,하지만 저는 정규 표현식으로 제한됩니다. 오리지널 포스트에서 배제한 긴 스토리에서. 그 일을 분명히하지 않으면 죄송합니다. –