Regex를 사용해 쉽게 패턴을 매치하거나 찾을 수 있다.
패턴을 찾기 전 잘 정의된 syntax를 하나 특정해야 한다.
이 문제에서 패턴은 주어진다. 그 구문(syntax)가 유효한지 확인해야 한다.
(이 문제에서 Regex는 Pattern.compile 메서드를 이용해 컴파일 가능할때에만 유효하다.)
테스트 케이스를 나타내는 정수 N이 첫줄에 입력되고, 다음 N 라인들에는 regex의 패턴을 나타내는 출력 가능한 모든 문자의 문자열이 포함된다.
각 테스트 케이스마다 주어진 syntax의 패턴이 정확하면 Valid를 출력한다.
아니면 Invalid. 따옴표는 출력되면 안된다.
Regex(Regular Expression)은 특정한 규칙을 가진 문자열의 집합을 표현하기 위해
쓰이는 형식 언어이다. 예컨대 전화번호, 주민번호, 이메일 등 정해진 형식이 있고,
그 형식을 사용자가 제대로 입력했는지 확인해야 하는 경우가 있다.
따라서 이런 입력값을 검증하는 용도로 regex를 사용하면 쉽게 구현할 수 있다.
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 패턴에 따라 분리합니다.
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() : 패턴내 그룹핑한(괄호지정) 전체 갯수를 반환합니다.
PatternSyntaxException
regex 패턴과 관련된 오류로, split() 메서드나 replaceAll() 메서드 등을
사용할 때 나타날 수 있는 에러다. 에러를 발생시킬 수 있는 특수문자들 앞에
역슬래시 \를 붙여 이스케이프 처리해주면 된다.
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"에 대한 내용이었던것
}
}
}