2019년 5월 23일 목요일

Hackerrank Day 28 RegEx, Patterns, and Intro to Databases







알고리즘 연습 사이트


Day 28:RegEx, Patterns, and Intro to Databases



 정규표현식(Regular expression)은 사용하려고 할 때마다 잊어버리고 다시 찾아보게 된다. 
 따라서 복습이 필요할 때마다 이 글을 참조하기 위해 기본 개념을 정리해 둔다.


* 참고 사이트

Pattern 클래스:  https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html
Matcher 클래스: https://docs.oracle.com/javase/8/docs/api/java/util/regex/Matcher.html
정규표현식 튜토리얼:  https://docs.oracle.com/javase/tutorial/essential/regex/
정규표현식 연습사이트: 여러가지 연습할 수 있는 사이트들이 많지만 regex101.com가 가장 편리한것 같다. 내가 만든 정규식에 대해 동작원리 설명이 나와있어 학습하기 편하다.
https://regex101.com/
https://rubular.com/r/UAgzl9NxQv


* Character Classes
 일반적으로 생각하는 자바의 클래스와 같은 의미가 아니라, 한개 혹은 한 개 이상의 문자들의 집합을 의미한다. 
 Character Class라는 것은 문자 그 자체이거나 문자의 범위를 표현하는 문법이 될 수 있다. 
 예를 들면 정규표현식 a는  a 문자 하나에 매칭될 것이다.
 \d라는 것은 정규표현식 문법인데 미리 정의된 캐릭터 클래스라는 것이다. 의미는 a digit(숫자) 을 뜻한다. 
\d와 동일한 표현으로 [0-9] 역시, 0부터 9까지의 숫자중에 한 개만 일치하면 된다는 조건이다.

 점(.) 은 정규표현식 문법 중 [ ] (bracketed character class) 안에서는 일반 점(.) 문자를 의미하지만,
[ ] 밖에서는 개행문자(\n)를 제외한 아무 문자한 개를 뜻하는 Character Class이다. 
 고로 [ ] 밖에서도 일반 문자처럼 사용하고 싶다면 \(back slash, 역슬래시) 를 앞에 붙여서 escape 해야 한다.


* Quantifier(수량사)
캐릭터 클래스 뒤에 붙어서 그 캐릭터클래스가 몇 번을 반복하는지 조건을 설정 하는 문법이다.


X? : X가 1개 이거나 0개의 횟수
X+ : X가 1개 이거나 그 이상의 횟수 
X* : X가 0개 이거나 그 이상의 횟수 
X{n} : X가 정확히 n번의 횟수
X{n, } : X가 최소 n번의 횟수
X{n,m} : X가 최소 n번에서 m번 사이의 횟수 (m횟수 포함)

^ , $
 캐릭터 클래스 앞에 ^ 이 문자가 오게 되면 그 캐릭터 클래스가 첫번째 문자여야 한다는 의미이다. 
 그러나 [ ] 안에 ^ 문자가 존재한다면 not 이 된다. 
 예를 들면 ^[a].+ 혹은 ^a.+은 a로 시작하는 2개 혹은 그 이상의 문자를 찾아내지만, ^[^a].+은 a로 시작하지 않는 2개 혹은 그 이상의 문자를 찾아낸다.
 $는 바로 앞의 캐릭터 클래스로 끝나야 함을 나타낸다.

 이번 문제는 이름과 이메일 주소를 공백으로 연결하여 입력값이 주어진다. 이메일 주소는 반드시 @gmail.com 이여야 하며 이름은 20자를 넘을 수 없다. 
전체 이메일 주소 길이는 50자를 넘을 수 없다.
위 조건에 맞는 이메일 주소를 가진 이름을 오름차순으로 정렬해야 한다.  

public class Solution {
    
    private static final Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) {
        int N = scanner.nextInt();
        scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
        String regexEmailId = "[a-z]{1,40}@gmail\\.com";
        String regexFirstName = "[a-z]{1,20}";
        Pattern pEmailId = Pattern.compile(regexEmailId);
        Pattern pfirstName = Pattern.compile(regexFirstName);
        List<String> resultList = new ArrayList<String>();

        for (int NItr = 0; NItr < N; NItr++) {
            String[] firstNameEmailID = scanner.nextLine().split(" ");

            String firstName = firstNameEmailID[0];

            String emailID = firstNameEmailID[1];

            Matcher firstNameM = pfirstName.matcher(firstName);
            Matcher emailM = pEmailId.matcher(emailID);

            if(!emailM.find()){
                continue;
            }
            if(firstNameM.find()){
                resultList.add(firstName);
            }
            
        }
        Collections.sort(resultList);
        for(String temp : resultList)
            System.out.println(temp);

        scanner.close();
    }
}

댓글 없음:

댓글 쓰기