2011-04-14 3 views
17

정규식을 사용하여 출력의 유효성을 검사하는 테스트가 있습니다. 실패하면 출력 X가 정규 표현식 Y와 일치하지 않는다고보고합니다.자바 API를 사용하여 정규 표현식이 일치하지 않는 부분을 확인하는 방법

문자열에서 일치가 실패한 부분에 대한 표시를 추가하고 싶습니다. 예 : matcher가 backtracking 전에 문자열에서 가장 멀리있는 것은 무엇입니까? Matcher.hitEnd()은 내가 찾고있는 것 중 하나입니다. 그러나 좀 더 일반적인 것을 원합니다.

이 작업을 수행 할 수 있습니까?

+1

이 아마 당신의 최선의 방법입니다 : http://stackoverflow.com/questions/2348694/how-do-you-debug-a-regex –

+0

@Reverend Gonzo : 고마워, 펄의 "use re 'debug'는 내가 찾고있는 것에 가깝다. Java에서 호출 할 수있는 비슷한 것이 좋습니다. – TimK

답변

5

을 일치에 실패하면 Match.hitEnd() 알려줍니다 긴 문자열이 일치 할 수 있는지 여부. 또한 입력 시퀀스에서 일치 항목을 찾기 위해 검색 할 영역을 지정할 수 있습니다. 경기가 실패 위치를 일치시킬 수없는 문자열이있는 경우 그래서, 당신은 볼의 접두사를 테스트 할 수 있습니다 :이 클래스의 출력은

import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

public class LastMatch { 
    private static int indexOfLastMatch(Pattern pattern, String input) { 
     Matcher matcher = pattern.matcher(input); 
     for (int i = input.length(); i > 0; --i) { 
      Matcher region = matcher.region(0, i); 
      if (region.matches() || region.hitEnd()) { 
       return i; 
      } 
     } 

     return 0; 
    } 

    public static void main(String[] args) { 
     Pattern pattern = Pattern.compile("[A-Z]+[0-9]+[a-z]+"); 
     String[] samples = { 
       "*ABC", 
       "A1b*", 
       "AB12uv", 
       "AB12uv*", 
       "ABCDabc", 
       "ABC123X" 
     }; 

     for (String sample : samples) { 
      int lastMatch = indexOfLastMatch(pattern, sample); 
      System.out.println(sample + ": last match at " + lastMatch); 
     } 
    } 
} 

입니다

:

*ABC: last match at 0 
A1b*: last match at 3 
AB12uv: last match at 6 
AB12uv*: last match at 6 
ABCDabc: last match at 4 
ABC123X: last match at 6 
+0

두 번째 사례가 혼란 스럽긴하지만 이것은 좋은 일입니다. 전체 문자열이 일치하므로 왜 4 번 보고서입니까? 나는 제안한다 : 'region.matches(); if (region.hitEnd()) ...'. 그런 다음 6을 반환합니다. – TimK

+0

잘자요. 부분 일치 만 테스트했고 전체 문자열 또는 해당 접두어와 일치하는 부분은 고려하지 않았습니다. 이 문제가 해결되었습니다. –

0

코드 외부에서 수행하려는 경우 코드에 붙여 넣기 전에 rubular을 사용하여 정규식을 테스트합니다.

+1

뭔가를 놓치지 않는 한, 이것은 텍스트가 정규식과 일치하지 않는 경우 나에게 알려주지 만 일치하지 않는 부분은 알려주지 않습니다. 그게 내가 원하는거야. – TimK

1

replaceAll() 한 쌍의 호출을 사용하여 입력 문자열의 양수 및 음수 일치를 나타낼 수 있습니다. 예를 들어, 16 진수 문자열의 유효성을 검사하려고한다고 가정 해 보겠습니다. 다음은 입력 문자열의 유효 문자와 유효하지 않은 문자를 나타냅니다.

String regex = "[0-9A-F]" 
String input = "J900ZZAAFZ99X" 
Pattern p = Pattern.compile(regex) 
Matcher m = p.matcher(input) 
String mask = m.replaceAll('+').replaceAll('[^+]', '-') 
System.out.println(input) 
System.out.println(mask) 

은 유효한 문자에서 + 및 잘못된 문자 아래 -로, 다음을 인쇄 할 것이다.

J900ZZAAFZ99X 
-+++--+++-++- 
3

당신은 문자열을 할 수 있으며, 모든 반복에 그것의 끝에서 한 번 더 문자를 제거, 그것을 반복하고 hitEnd() 확인 :

int farthestPoint(Pattern pattern, String input) { 
    for (int i = input.length() - 1; i > 0; i--) { 
     Matcher matcher = pattern.matcher(input.substring(0, i)); 
     if (!matcher.matches() && matcher.hitEnd()) { 
      return i; 
     } 
    } 
    return 0; 
} 
+0

intput.length() – ytg

관련 문제