스터디사이트 : https://www.hackerrank.com



JAVA Basic : 정규식 , 문자열 비교 및 오름차순 정렬


사용자 이름과 이메일을 입력받아서 아래 조건을 충족시키게 한 후, gmail.com 계정을 가지고 있는 사용자만 오름차순으로 출력하시오.


※ 조건

이름 : a-z 만 와야함, 20자 이하

이메일 : a-z , @ , '.'(점) 만 와야함, 50자 이하

@gmail.com으로 끝나는 이메일 중 이름만 추출해서 알파벳순으로 출력.




정규식

정규식의 쓰임은 다양하다

자주 쓰이는 정규식 클래스는 아마도 java.util.regex.Pattern; 일 것 같다.

이 Pattern 클래스 사용 시 주의해야 할 것이,

java.util.*; 을 통째로 import했다고 사용이 되는 것이 아니고,

코딩할 때 import java.util.regex.Pattern; 을 앞에다가 넣어줘야 먹힌다는 것이다.


정규식의 종류 : 

http://egloos.zum.com/xxwony/v/65474

http://devfalledinmac.tistory.com/14


필자가 지금까지 알아본 쓰임새는 2가지 케이스가 있는 것 같다.


케이스 1 - Pattern.matches()

String strInput = "Hello World!!";

boolean flag = Pattern.matches("^[a-zA-Z0-9]*$", strInput);


"Hello World!!" 란 값이 영문 a-z(소문자), A-Z(대문자)와 0-9(숫자)의 범위에 포함되느냐를 판가름할 때 쓰이는 식이다.

그런데 여기서 결과는 true가 나온다.


왜냐면.. Hello 까지만 정규식이 인식을 하는 것 같다.

사이띄기를 안하고 "HelloWorld!!" 라고 치면 false가 나온다.. ㅋㅋ


케이스 2 - Pattern.compile & String.split

public class SplitDemo2 {


    private static final String REGEX = "\\d";    // \\d : 모든 숫자범위. 아래 INPUT값들사이에 있는 숫자를 기준으로 문자를 나눌때 쓰임.

    private static final String INPUT =

        "one9two4three7four1five";


    public static void main(String[] args) {

        Pattern p = Pattern.compile(REGEX);    // \\d가 모든 숫자라고 했듯이 패턴을 내부적으로 컴파일한다고 이해하면 쉬울듯.

        String[] items = p.split(INPUT);        // 컴파일한 공간에다가 INPUT값을 넣으면, INPUT값 안의 숫자를 기준으로 나뉘어진 문자가

 items 배열에 들어가게 된다.

        for(String s : items) {

            System.out.println(s);

        }

    }

}


  결과:

one

two

three

four

five


문자열이 @gmail.com 으로 끝나는 식 구하기

이것도 필자가 아는 방법은 2가지가 있다.


케이스 1 - 정규식으로 구하기

String a = "000@gmail.com" 아니면 "hello@gmail.com";

boolean flag = Pattern.matches("[a-z]+@gmail\\.com$", a);

①번은 정규식의 [a-z] 조건을 충족 못하므로 결과는 false.

②번은 정규식의 조건을 모두 충족하므로 결과는 true.

정규식중 @gmail 다음에 오는 \\. 는 보통 정규식이 . 을 식으로 인식하니까 gmail.com의 점을 식으로 인식하지 말라는 의미로 붙인 듯 하다.


케이스 2 - String클래스의 endsWith() 메소드로 구하기

String email = "sjulia@gmail.com";

boolean isgmail = email.endsWith("@gmail.com");


결과는 true.


문자열 오름차순 정렬

String[] arr={"bb", "cc", "aa"};

Arrays.sort(arr);

for(int j = 0 ; j<arr.length; j++){

     System.out.println("\t" + j + "번째 arr[] : " + arr[j]);

}


  결과 :

0번째 arr[] : aa

1번째 arr[] : bb

2번째 arr[] : cc




입력

6

riya riya@gmail.com

julia julia@julia.me

julia sjulia@gmail.com

julia julia@gmail.com

samantha samantha@gmail.com

tanya tanya@gmail.com

출력

julia

julia

riya

samantha

tanya



디버깅 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    public static void main(String[] args) {
        // 이름 : a-z - 20자 이하
        // 이메일 : a-z , @ , '.'(점) - 50자 이하
        // @gmail.com으로 끝나는 이메일 중 이름만 추출해서 알파벳순으로 출력.
        Scanner scan = new Scanner(System.in);
            //scan.useDelimiter("\n");
        
        int i = scan.nextInt();
        while( i-- >0 ){
            System.out.println("[" + i + "차 시도]");
            String name = scan.next();
            String email = scan.next();
            
                //System.out.println(a);           
            boolean isnamelength = Pattern.matches("\\w{5}", name);
            boolean isname = Pattern.matches("^[a-z]*$", name);            
            System.out.print("이름이 20자 안에 속하냐? " + isnamelength);
            System.out.println(" // a-z이느냐? " + isname); 
                        
            boolean ismaillength = Pattern.matches("\\w{50}", email);
            boolean isgmail = email.endsWith("@gmail.com");
            System.out.print("이메일이 50자 안에 속하냐? " + ismaillength);
            System.out.println(" // @gmail.com으로 끝나느냐? " + isgmail); 
        }
    }
cs

결과 : 

[5차 시도]

이름이 20자 안에 속하냐? false // a-z이느냐? true

이메일이 50자 안에 속하냐? false // @gmail.com으로 끝나느냐? true

[4차 시도]

이름이 20자 안에 속하냐? true // a-z이느냐? true

이메일이 50자 안에 속하냐? false // @gmail.com으로 끝나느냐? false

[3차 시도]

이름이 20자 안에 속하냐? true // a-z이느냐? true

이메일이 50자 안에 속하냐? false // @gmail.com으로 끝나느냐? true

[2차 시도]

이름이 20자 안에 속하냐? true // a-z이느냐? true

이메일이 50자 안에 속하냐? false // @gmail.com으로 끝나느냐? true

[1차 시도]

이름이 20자 안에 속하냐? false // a-z이느냐? true

이메일이 50자 안에 속하냐? false // @gmail.com으로 끝나느냐? true

[0차 시도]

이름이 20자 안에 속하냐? true // a-z이느냐? true

이메일이 50자 안에 속하냐? false // @gmail.com으로 끝나느냐? true

▷ Feedback :

정규식에다가 or 조건을 줘갖고 테스트를 함 해봤는데 안된다는 것을 알았네? ㅎ

변수로 정의한 isname과 islength의 순서와 다르게 출력을 반대로 해서 헷갈릴 수 있는 점 이해해 주긜..

그리고  \\w{5}  라는 정규식의 의미는 5글자 이하를 보는 게 아니라 딱 5글자인지 판단할 때 쓰이는 식이라는걸 알았다.. ㅋ


 \\w{1,5}  라고 써 주어야 1자리수 이상 5자리 이하를 판별할 수 있는 식이다.


그리고 이메일은!   \\D{1,50}  으로 정규식을 주어야한다.

\w : 알파벳이나 숫자

\D : 숫자를 제외한 모든 문자

이기 때문이다..


이제 위의 조건을 충족하는 사용자이름을 배열에 넣어서 오름차순 정렬하는 일을 추가 해 주면 될 듯 하다.



디버깅 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
    public static void main(String[] args) {
        // 이름 : a-z - 20자 이하
        // 이메일 : a-z , @ , '.'(점) - 50자 이하
        // @gmail.com으로 끝나는 이메일 중 이름만 추출해서 알파벳순으로 출력.
        Scanner scan = new Scanner(System.in);
            //scan.useDelimiter("\n");
        
        int i = scan.nextInt();
        List<String> userlist = new ArrayList<String>();
        while( i-- >0 ){
            System.out.println("[" + i + "차 시도]");
            String name = scan.next();
            String email = scan.next();
            
                //System.out.println(a);           
            boolean isnamelength = Pattern.matches("\\w{1,20}", name);
            boolean isname = Pattern.matches("^[a-z]*$", name);            
            System.out.print("이름이 20자 안에 속하냐? " + isnamelength);
            System.out.println(" // a-z이느냐? " + isname); 
                        
            boolean ismaillength = Pattern.matches("\\D{1,50}", email);
            boolean isgmail = email.endsWith("@gmail.com");
            System.out.print("이메일이 50자 안에 속하냐? " + ismaillength);
            System.out.println(" // @gmail.com으로 끝나느냐? " + isgmail); 
            
            if(isnamelength && isname && ismaillength && isgmail){
                userlist.add(name);
            }
        }
        String[] arr = userlist.toArray(new String[userlist.size()]);
        Arrays.sort(arr);
        for(int j = 0 ; j<userlist.size(); j++){
            System.out.println(j + "번째 List : " + userlist.get(j));
            System.out.println("\t" + j + "번째 arr[] : " + arr[j]);
        }
    }
cs

결과 : 

[5차 시도]

이름이 20자 안에 속하냐? true // a-z이느냐? true

이메일이 50자 안에 속하냐? true // @gmail.com으로 끝나느냐? true

[4차 시도]

이름이 20자 안에 속하냐? true // a-z이느냐? true

이메일이 50자 안에 속하냐? true // @gmail.com으로 끝나느냐? false

[3차 시도]

이름이 20자 안에 속하냐? true // a-z이느냐? true

이메일이 50자 안에 속하냐? true // @gmail.com으로 끝나느냐? true

[2차 시도]

이름이 20자 안에 속하냐? true // a-z이느냐? true

이메일이 50자 안에 속하냐? true // @gmail.com으로 끝나느냐? true

[1차 시도]

이름이 20자 안에 속하냐? true // a-z이느냐? true

이메일이 50자 안에 속하냐? true // @gmail.com으로 끝나느냐? true

[0차 시도]

이름이 20자 안에 속하냐? true // a-z이느냐? true

이메일이 50자 안에 속하냐? true // @gmail.com으로 끝나느냐? true

0번째 List : riya

0번째 arr[] : julia

1번째 List : julia

1번째 arr[] : julia

2번째 List : julia

2번째 arr[] : riya

3번째 List : samantha

3번째 arr[] : samantha

4번째 List : tanya

4번째 arr[] : tanya

▷ Feedback :

이름이 20자 안팎 소문자를 만족하고, 이메일이 50자 안팎 @gmail.com 계정을 가지고 있다면 ArrayList배열에 사용자 이름을 넣었고,

오름차순 정렬을 위한 Arrays.sort() 메소드 안의 파라미터는 String[] 배열이므로, ArrayList배열을 toArray() 메소드로 String[] 배열로 바꿨다.

이렇게 String[] 배열로 변환 후, Arrays.sort()메소드로 오름차순 정렬을 하였다.


이제 디버깅들은 다 주석처리하고 돌려보면 될듯


디버깅 3 & 결과

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
    public static void main(String[] args) {
        // 이름 : a-z - 20자 이하
        // 이메일 : a-z , @ , '.'(점) - 50자 이하
        // @gmail.com으로 끝나는 이메일 중 이름만 추출해서 알파벳순으로 출력.
        Scanner scan = new Scanner(System.in);
            //scan.useDelimiter("\n");
        
        int i = scan.nextInt();
        List<String> userlist = new ArrayList<String>();
        while( i-- >0 ){
                //System.out.println("[" + i + "차 시도]");
            String name = scan.next();
            String email = scan.next();
                       
            boolean isnamelength = Pattern.matches("\\w{1,20}", name);
            boolean isname = Pattern.matches("^[a-z]*$", name);            
                //System.out.print("이름이 20자 안에 속하냐? " + isnamelength);
                //System.out.println(" // a-z이느냐? " + isname); 
                        
            boolean ismaillength = Pattern.matches("\\D{1,50}", email);
            boolean isgmail = email.endsWith("@gmail.com");
                //System.out.print("이메일이 50자 안에 속하냐? " + ismaillength);
                //System.out.println(" // @gmail.com으로 끝나느냐? " + isgmail); 
            
            if(isnamelength && isname && ismaillength && isgmail){
                userlist.add(name);
            }
        }
        String[] arr = userlist.toArray(new String[userlist.size()]);
        Arrays.sort(arr);
        for(int j = 0 ; j<userlist.size(); j++){
            //System.out.println(j + "번째 List : " + userlist.get(j));
            //System.out.println("\t" + j + "번째 arr[] : " + arr[j]);
            System.out.println(arr[j]);
        }
    }
cs

결과 : 

julia

julia

riya

samantha

tanya

▷ Feedback :

끋.


'JAVA > JAVA Basic' 카테고리의 다른 글

JAVA Basic : bitwise AND(비트연산 AND)  (0) 2016.10.06
JAVA Basic : 중첩 로직  (0) 2016.10.02
JAVA Basic : 제네릭  (0) 2016.07.27
JAVA Basic : 인터페이스  (0) 2016.07.18
JAVA Basic : 예외처리 - throw  (0) 2016.07.17

+ Recent posts