22.4.28 [HackerRank]Java Pattern Syntax Checker

서태욱·2022년 4월 28일
0

Algorithm

목록 보기
18/45
post-thumbnail

✅ 문제 분석

Regex를 사용해 쉽게 패턴을 매치하거나 찾을 수 있다.
패턴을 찾기 전 잘 정의된 syntax를 하나 특정해야 한다.

이 문제에서 패턴은 주어진다. 그 구문(syntax)가 유효한지 확인해야 한다.
(이 문제에서 Regex는 Pattern.compile 메서드를 이용해 컴파일 가능할때에만 유효하다.)

테스트 케이스를 나타내는 정수 N이 첫줄에 입력되고, 다음 N 라인들에는 regex의 패턴을 나타내는 출력 가능한 모든 문자의 문자열이 포함된다.

각 테스트 케이스마다 주어진 syntax의 패턴이 정확하면 Valid를 출력한다.
아니면 Invalid. 따옴표는 출력되면 안된다.

🌱 배경지식

자바 정규 표현식 (Pattern, Matcher)

Regex(Regular Expression)은 특정한 규칙을 가진 문자열의 집합을 표현하기 위해
쓰이는 형식 언어이다. 예컨대 전화번호, 주민번호, 이메일 등 정해진 형식이 있고,
그 형식을 사용자가 제대로 입력했는지 확인해야 하는 경우가 있다.
따라서 이런 입력값을 검증하는 용도로 regex를 사용하면 쉽게 구현할 수 있다.

  1. Pattern 클래스
    java.util.rege.Pattern 클래스의 matches()메소드를 활용해 regex의 대상 문자열을
    검증할 수 있다. 첫번째 파라미터는 regex이고 두번째 파라미터는 검증 대상 문자열이다.
    검증 후 regex와 일치하면 true, 아니면 false가 반환된다.
import java.util.regex.Pattern;

public class RegexExample {
	public static void main(String[] args)  {
    
            String pattern = "^[0-9]*$"; //숫자만
            String val = "123456789"; //대상문자열
        
            boolean regex = Pattern.matches(pattern, val);
            System.out.println(regex);
    }
}

// 결과: true 반환

Pattern 클래스 주요 메서드
compile(String regex) : 주어진 정규표현식으로부터 패턴을 만듭니다.
matcher(CharSequence input) : 대상 문자열이 패턴과 일치할 경우 true를 반환합니다.
asPredicate() : 문자열을 일치시키는 데 사용할 수있는 술어를 작성합니다.
pattern() : 컴파일된 정규표현식을 String 형태로 반환합니다.
split(CharSequence input) : 문자열을 주어진 인자값 CharSequence 패턴에 따라 분리합니다.

  1. Matcher 클래스
    이 클래스는 대상 문자열의 패턴을 해석해 주어진 패턴과 일치하는지를 검증해준다.
    CharSequence라는 인터페이스가 사용된다. 이를 통해 다양한 형태의 입력 데이터로부터
    문자 단위의 매칭 기능을 지원받을 수 있다.
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexExample {
	public static void main(String[] args)  {
            Pattern pattern = Pattern.compile("^[a-zA-Z]*$"); //영문자만
            String val = "abcdef"; //대상문자열
	
            Matcher matcher = pattern.matcher(val);
            System.out.println(matcher.find());
	}
}

// 결과: true 반환

Matcher 클래스 주요 메서드
matches() : 대상 문자열과 패턴이 일치할 경우 true 반환합니다.
find() : 대상 패턴이 일치하는 경우 true를 반환하고, 그 위치로 이동합니다.
find(int start) : start위치 이후부터 매칭검색을 수행합니다.
start() : 매칭되는 문자열 시작위치 반환합니다.
start(int group) : 지정된 그룹이 매칭되는 시작위치 반환합니다.
end() : 매칭되는 문자열 끝 다음 문자위치 반환합니다.
end(int group) : 지정되 그룹이 매칭되는 끝 다음 문자위치 반환합니다.
group() : 매칭된 부분을 반환합니다.
group(int group) : 매칭된 부분중 group번 그룹핑 매칭부분 반환합니다.
groupCount() : 패턴내 그룹핑한(괄호지정) 전체 갯수를 반환합니다.

  1. PatternSyntaxException
    regex 패턴과 관련된 오류로, split() 메서드나 replaceAll() 메서드 등을
    사용할 때 나타날 수 있는 에러다. 에러를 발생시킬 수 있는 특수문자들 앞에
    역슬래시 \를 붙여 이스케이프 처리해주면 된다.

  2. try catch문
    try 문에서 Exception 예외가 발생할 경우 catch (Exception e)
    로 빠져서 그 안의 실행문을 실행한다.

try { 
//예외발생할 가능성이 있는 문장 

}catch(Exception1 e1) { 
//Exception1이 발생했을 경우, 이를 처리하기 위한 문장을 적는다. 
//보통 이곳에 예외메세지를 출력하고 로그로 남김. 

}catch(Exception2 e2) { 
//Exception2이 발생했을 경우, 이를 처리하기 위한 문장을 적는다. 

}catch(ExceptionN eN) { 
//ExceptionN이 발생했을 경우, 이를 처리하기 위한 문장을 적는다.

}finally{ 
//예외발생여부에 관계없이 상항 수행되어야 하는 문장적는다. 

}

✏️ 해설

import java.util.Scanner;
import java.util.regex.*;

public class Solution
{
	public static void main(String[] args){
		Scanner in = new Scanner(System.in);
        // parseInt 숫자형의 문자열을 int로 변환해 줌
		int testCases = Integer.parseInt(in.nextLine());
		while(testCases > 0){ 
        //반복문의 조건식이 hasNext()와 같이 boolean 타입을 리턴하는 경우에는 
        //for문보다 while문을 사용하는 것이 코드의 효율성과 속도를 향상시켜 준다.
			String pattern = in.nextLine();
          	//Write your code
            testCases--;
            try {
                Pattern.compile(pattern);
                System.out.println("Valid");
            }
            catch (PatternSyntaxException e) {
                System.out.println("Invalid");
            }
// while 반복문이 적절하게 조건을 돌 수 있도록 하나씩 감소시키는 조건을 준다.
//자꾸 런타임 에러가 나서 찾아보니 scanner에서 nextLine() 함수는 더 이상 입력받을 줄이 없을 경우
// 에러(java.util.NoSuchElementException: No line found)를 발생시킨다고 한다.
//이 문제와 같이 입력이 몇 줄이나 주어지는지 알 수 없는 경우 남은 줄이 있는지
// hasNextLine() 메서드 같은 것으로 확인해 줘야 한다고 한다. "EOF"에 대한 내용이었던것
		}
	}
}

👉 참고

profile
re:START

0개의 댓글