2013-10-25 5 views
1

regex를 사용하여 입력 할 때 사용자 입력의 유효성을 검사하려고합니다.java 정규식이 패턴보다 짧음

내 패턴은 다음과 같습니다. "(\\w{3})(\\d{7})(\\w{3})". 유효한 입력은 "XYZ0001112CCC" 일 수 있습니다.

사용자 유형으로 유효성을 검사하고 싶습니다. 나는 "A", "AB", "ABC", "ABC12", "ABC123", ..., "ABC1234567XY"도 실패하지 말아야한다. 그러나 "A1", "AB2", "ABCD123", ..., "ABC1234567XY1"은 실패해야합니다. 입력이 규칙을 위반하지 않는 한이 규칙을 "지금까지 유효한 것으로"간주하려고합니다. 정규 표현식이 가능합니까?

답변

1

: 하나 ([a-zA-Z]+)(\d+)([a-zA-Z]+)

그런 다음 각 그룹에 얼마나 많은 편지 확인할 수 있습니다 다음 부분을 첫 글자 다음에 입력하고, lookbehind를 사용하여 입력의 이전 부분을 확인합니다. 예를 들어

:

//       |first letters (1 to 3) 
//          | if 3 letters precede... 
//               | digits (1 to 7) 
//                 | if 7 digits precede... 
//                    | 3 letters 
Pattern p = Pattern.compile("[a-zA-Z]{1,3}((?<=[a-zA-Z]{3})\\d{1,7})?((?<=\\d{7})[a-zA-Z]{3})?"); 
String[] inputs = {"XYZ0001112CCC", "A", "AB", "ABC", "ABC12", "ABC123", "A1", "AB2", "ABCD123","ABC1234567XY1"}; 
Matcher m; 
for (String input: inputs) { 
    m = p.matcher(input); 
    System.out.println("Input: " + input + " --> Matches? " + m.matches()); 
} 

출력 :

Input: XYZ0001112CCC --> Matches? true 
Input: A --> Matches? true 
Input: AB --> Matches? true 
Input: ABC --> Matches? true 
Input: ABC12 --> Matches? true 
Input: ABC123 --> Matches? true 
Input: A1 --> Matches? false 
Input: AB2 --> Matches? false 
Input: ABCD123 --> Matches? false 
Input: ABC1234567XY1 --> Matches? false 

\\w도 자리 유효성을 검사하기 때문에 나는 문자 클래스 [a-zA-Z]\\w 표현을 변경했습니다. [a-zA-Z]에 대안은 다음과 같습니다

Pattern는 3 문자 그룹으로 마지막 편지를 취

  • \\p{Alpha}
  • [a-z]

최종 메모 플래그 Pattern.CASE_INSENSITIVE와 함께. 1 ~ 2 자까지 입력 할 수있는 경우 마지막 한정자 식 {3}{1,3}으로 변경하면됩니다.형식이 오히려 쉽기 때문에

+0

왜 ABC12 또는 ABC123이 false를 반환합니까? –

+0

@Tim my bad, 나는 첫 번째 3 글자 다음의 전체 입력에 대해 "한 번 또는 전혀"한정 기호를 사용했습니다. 결정된. – Mena

+0

감사합니다. @ 메나. 지금은 괜찮아 보인다. 나는 정규식에 익숙하지 않다. 하지만 당신은 그런 상황에 대한 정규 표현을 제안합니까? 작동하지만 성능에 대한 고려 사항도 있습니다. 이것은 정규식 사용에 편리한 상황입니까? –

0

유효성 검사를 valid-so-far 유효성 확인과 최종 확인을위한 두 개의 정규 표현식으로 분할하는 것이 좋습니다.

그렇다면 그 사실을 검증하는 것은 간단하지 않습니다. ABC1은 지금까지 유효합니다. (\\w{0,3})(\\d{0,7})(\\w{0,3})과 같은 패턴은 X0C이 올바르지 않은 것으로 간주되므로 잘리지 않습니다. 따라서 정규 표현식만으로이 문제를 해결하려고하지는 말고 코딩 된 논리를 사용하는 것이 좋습니다.

(lookbehinds 또는 if-then-else conditionals를 사용하여 하나의 정규 표현식으로 모든 유효성 검사 논리를 짜내는 가능하지만, 나는 그렇게하지 않는 것이 좋습니다. 그것은 읽을 수 및 유지 보수가 어려운입니다.)

+0

'유효 기간 만료'제안이 있으십니까? 많은 가능성이 없을까요? –

+0

@Tim 당신은 그 복잡성을 받아 들일지 여부를 스스로 판단해야하지만, 답변은 메나 쇼처럼 하나의 정규식에 모두 맞출 수 있습니다. –

1

당신은 간단에 패턴을 변화시킬 수 나는 개를 위해 "한 번 또는 전혀"한정 기호의 조합을 사용

Pattern p = Pattern.compile("([a-zA-Z]+)(\d+)([a-zA-Z]+)"); 
Matcher matcher = p.matcher("ABC1234567XYZ"); 
if (matcher.find()) { 
    String firstLetters = matcher.group(1); 
    String digits = matcher.group(2); 
    String lastLetters = matcher.group(3); 

    //any checks here 
} 
+0

IllegalStateException : 일치하는 항목이 없습니다. –

+0

이상하게도 일치하는 것을 찾지 못했습니다. \ w 또한 밑줄 + 숫자를 취하고 적어도 하나 이상의 일치에 +가 필요하기 때문에 패턴을 업데이트했습니다. – Admit

+0

제안 된 패턴은 ([a-zA-Z] *) (\\ d *) ([a-zA-Z] *)이어야한다고 생각합니다. 이것도 좋은 해결책이지만, 모든 검사가 정규식 내에서 완료 되었기 때문에 Mena의 해결책이 나에게 좋을 것 같습니다. –

0

, 당신은 같은 것을 할 수있는 (I 정확한 자바 구문을 모르겠어요,하지만 난 생각이 분명하다 생각) :

String input = "DEF3"; 
String example = "ABC1234567XY"; 
Pattern regex = Pattern.compile("(\\w{3})(\\d{7})(\\w{3})"); 

String test_input = input + example.last_digits(example.length-input.length); 
Matcher matcher = p.matcher(test_input); 
return matcher.find(); 

이 방법을 유일하게 중복 당신 have가 예제와 정규 표현식 사이에있다.