2014-09-03 2 views
0

Java의 구분 기호 사이에서 여러 줄의 텍스트를 어떻게 대응시킬 수 있습니까? 가장 좋은 예로 설명Java에서 구분 기호 사이의 여러 텍스트 줄 일치

질문 : 위에서

... 
unimportant text 
EndOfEntry 
Key=Value 
unimportant text 
maybe a few lines of unimportant text 
AnotherKey=AnotherValue 
EndOfEntry 
more unimportant text 
... 

, 나는 키 = 값에 일치시킬 * AnotherKey = anotherValue라는 함께 하나 개의 항목에 출연 한.. 패턴이 나타나는지 간단히 알기 만하면됩니다. 아무 것도 대체 할 필요가 없습니다.

그러나 동일한 원하는 경기와 같은 여러 항목이 주어진 경우 : 우리가 = 정확히 키를 참조하지 않기 때문에

... 
unimportant text 
EndOfEntry 
Key=Value 
unimportant text 
maybe a few lines of unimportant text 
AnotherKey=NotMyValue 
EndOfEntry 
RandomKey=Value 
unimportant text 
maybe a few lines of unimportant text 
AnotherKey=AnotherValue 
EndOfEntry 
more unimportant text 
... 

을 나는 성공적으로 일치하기 위 싶지 않을 것이다 가치와 AnotherKey = 하나의 "항목"내의 AnotherValue. 대신 첫 번째 항목에는 Key = Value가 표시되고 두 번째 항목에는 AnotherKey = AnotherValue가 표시됩니다. 내가 좋아하는 정규식과 노력했습니다

(물론 \ S \ S 패턴에 대한 DOTALL 옵션으로 대체 될 수 있습니다) :

Key=Value[\S\s]*?AnotherKey=AnotherValue 

하지만 모두 일치 물론

. 나는 또한 시도했다 :

Key=Value[^EndOfEntry]*?AnotherKey=AnotherValue 

그러나 점이없고 우리는 전혀 일치하지 않으므로 작동하지 않는다.

찾고있는 것과 일치하는 하나의 정규식이 있습니까? 줄 바꿈을 먼저 제거하거나 다른 두 단계 처리 (단순히 교육을 위해 피하려고합니다)를 단순화합니까?

+0

나는 당신의 필요를 분명히 아니에요 . 더 나은 입력 예제와 원하는 출력을 넣을 수 있습니까? –

+0

'Key = Value [\ S \ s] *? AnotherKey = AnotherValue [\ S \ s] *? EndOfEntry' 당신이 찾고있는 것을 해보시겠습니까? 각 항목은 Key = Value로 시작해야합니까? – adamdc78

+1

신경 쓰지 마라. 네가보기에 너무 많이 부합 할 것이므로 부정적 시각이 필요하다. 정규 표현식은 올바른 도구가 아닐 수도 있습니다. – adamdc78

답변

2

당신은 단순히 사용해야

\bKey=Value\b(?:(?!EndOfEntry).)*?\bAnotherKey=AnotherValue\b 

을합니다 (DOTALL 플래그와 함께, 당신은 귀하의 질문에 제안).

실험실은 here on regex101입니다. 작동 원리


는 :

나는 기본적으로 간단하게 교체 한 당신의 그 표현에 의해 .* : EndOfEntry을 포함하지 않는 약 것을 나타냅니다 ((?!EndOfEntry).)*. (

내가 \b와 쌍을 포위했습니다 RandomKey=Value도 (예를 들어) Key=Value 일치하는 것이기 때문에

또한, 내가 추가 한, 쌍 RandomKey=ValueAnotherKey=AnotherValue과 일치하는 다른 약간의 비틀기를 피하기 위해 우리는 단어 경계에 있음을 주장합니다.) (또는 공백 문자의 경우 \s) 전체 단어가 일치 할 때만 일치합니다.여기


내가 당신의 예에 대해 제안하고있어 정규식을 사용 자바 코드 조각입니다 :

final Pattern pattern = Pattern.compile("\\bKey=Value\\b(?:(?!EndOfEntry).)*?\\bAnotherKey=AnotherValue\\b", Pattern.DOTALL); 

final String invalid = "unimportant text\n" + 
       "EndOfEntry\n" + 
       "Key=Value\n" + 
       "unimportant text\n" + 
       "maybe a few lines of unimportant text\n" + 
       "AnotherKey=NotMyValue\n" + 
       "EndOfEntry\n" + 
       "RandomKey=Value\n" + 
       "unimportant text\n" + 
       "maybe a few lines of unimportant text\n" + 
       "AnotherKey=AnotherValue\n" + 
       "EndOfEntry\n" + 
       "more unimportant text"; 

final String valid = "unimportant text\n" + 
       "EndOfEntry\n" + 
       "Key=Value\n" + 
       "unimportant text\n" + 
       "maybe a few lines of unimportant text\n" + 
       "AnotherKey=AnotherValue\n" + 
       "EndOfEntry\n" + 
       "more unimportant text"; 

System.out.println(pattern.matcher(invalid).find()); 
System.out.println(pattern.matcher(valid).find()); 

출력 :

false 
true 
+0

자바에서 작동하지 않는다고 생각합니다. regex101조차도 첫 번째 캡처 그룹이 잘못되었습니다. – adamdc78

+0

나는 그것이 실제로 작동한다고 생각하고 regex101에서 그 예제에 무엇이 잘못되었는지 보지 못한다. 어쩌면 질문을 올바르게 이해하지 못했을 수도 있습니다. 나는 OP가 내 대답을 보일지 만 내가 맞을지를 대비해 주겠다. – ccjmne

+0

Ahh, 문제를 일으키지 않은 그룹을 캡쳐하지 않았다. regexplanet (실제 Java 정규 표현식 테스터)에서 실행했을 때 제공된 입력과 일치하지 않았습니다. 비록 당신이 자바 코드를 가지고 있다면 RegexPlanet을 통해 그것을 취할 것입니다. 나는 교정했다. 편집 : 나는 유효한 문자열을 기준으로 포함 시키면 도움이되었을 것입니다. 내 잘못이야! – adamdc78

관련 문제