본문

정규식(Regular Expression)

반응형

# 정규식(Regular Expression)

정규식이란 텍스트 데이터 중에서 원하는 조건(패턴, pattern)과 일치하는 문자열을 찾아내기 위해 사용하는 것으로
미리 정의된 기호와 문자를 이용해서 작성한 문자열을 말한다. 

정규식을 이용하면 많은 양의 텍스트 파일 중에서 원하는 데이터를 손쉽게 뽑아낼 수도 있고
입력된 데이터가 형식에 맞는지 체크할 수 도 있다
.

예를들면 html문서에서 전화번호나 이메일 주소만을 따로 추출한다던가
입력한 비밀번호가 숫자와 영문자의 조합으로 되어 있는지 확인할 수 도 있다.


data라는 문자열배열에 담긴 문자열 중에서 지정한 정규식과 일치하는 문자열을 출력하는 예제이다.

Source 01) RegularExpressionEx01.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package regularExpressionEx;
 
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
public class RegularExpressionEx01 {
 
    public static void main(String[] args) {
        String[] data = { "bat""baby""bonus""cA""ca""co""c.""c0""car""combat""count""date","disc" };
 
        Pattern p = Pattern.compile("c[a-z]*"); // c로 시작하는 소문자영단어
 
        for (int i = 0; i < data.length; i++) {
            Matcher m = p.matcher(data[i]);
            if (m.matches())
                System.out.print(data[i] + ",");
        }
    }
}
cs

Result)

1
ca,co,car,combat,count,
cs


Pattern은 정규식을 정의하는데 사용되고 Matcher는 정규식(패턴)을 데이터와 비교하는 역할을 한다.


Source 02) RegularExpressionEx02.java

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
package regularExpressionEx;
 
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
public class RegularExpressionEx02 {
 
    public static void main(String[] args) {
        String[] data = { "bat""bady""bonus""c""cA""ca""co""c.""0""c#""car""combat""count""date""disc" };
        
        // .* : 모든 문자열
        String[] pattern = { ".*""c[a-z]*""c[a-z]""c[a-zA-z]""c[a-zA-Z0-9]""c.""c.*""c\\.""c\\w""c\\d",
                "c.*t""[b|c].*"".*a.*"".*a.+""[b|c].{2}" };
 
        for (int x = 0; x < pattern.length; x++) {
            Pattern p = Pattern.compile(pattern[x]);
            System.out.println("Pattern : " + pattern[x] + "결과 : ");
 
            for (int i = 0; i < data.length; i++) {
                Matcher m = p.matcher(data[i]);
                if (m.matches())
                    System.out.println(data[i] + ".");
            }
 
            System.out.println();
        }
    }
}
cs

Result)

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
Pattern : .*결과 : 
bat.
bady.
bonus.
c.
cA.
ca.
co.
c..
0.
c#.
car.
combat.
count.
date.
disc.
 
Pattern : c[a-z]*결과 : 
c.
ca.
co.
car.
combat.
count.
 
Pattern : c[a-z]결과 : 
ca.
co.
 
Pattern : c[a-zA-z]결과 : 
cA.
ca.
co.
 
Pattern : c[a-zA-Z0-9]결과 : 
cA.
ca.
co.
 
Pattern : c.결과 : 
cA.
ca.
co.
c..
c#.
 
Pattern : c.*결과 : 
c.
cA.
ca.
co.
c..
c#.
car.
combat.
count.
 
Pattern : c\.결과 : 
c..
 
Pattern : c\w결과 : 
cA.
ca.
co.
 
Pattern : c\d결과 : 
 
Pattern : c.*t결과 : 
combat.
count.
 
Pattern : [b|c].*결과 : 
bat.
bady.
bonus.
c.
cA.
ca.
co.
c..
c#.
car.
combat.
count.
 
Pattern : .*a.*결과 : 
bat.
bady.
ca.
car.
combat.
date.
 
Pattern : .*a.+결과 : 
bat.
bady.
car.
combat.
date.
 
Pattern : [b|c].{2}결과 : 
bat.
car.
cs



Source 03) RegularExpressionEx03.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package regularExpressionEx;
 
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
public class RegularExpressionEx03 {
 
    public static void main(String[] args) {
        String source = "HP:010-1111-1111, HOME:02-999-9999";
        String pattern = "(0\\d{1,2})-(\\d{3,4})-(\\d{4})";
 
        Pattern p = Pattern.compile(pattern);
        Matcher m = p.matcher(source);
 
        int i = 0;
        while (m.find()) {
            System.out.println(+++ ": " + m.group() + " -> " + m.group(1+ ", " + m.group(2+ ", " + m.group(3));
        }
    }
}
cs

Result)

1
2
1010-1111-1111 -> 01011111111
202-999-9999 -> 029999999
cs


정규식의 일부를 괄호로 나누어 묶어서 그룹화할 수 있다. 그룹화된 부분은 하나의 단위로 묶이는 셈이 되어서 한 번 또는 그 이상의 반복을 의미하는 '+'나 '*'가 뒤에 오면 그룹화된 부분이 적용대상이 된다. 그리고 그룹화된 부분의 group(int i)를 이용해서 나누어 얻을 수 있다.

정규식 패턴 

설 명 

 0\\d{1,2}

 0으로 시작하는 최소 2자리 최대 3자리 숫자(0포함)

 \\d{3,4}

 최소 3자리 최대 4자리 숫자

 \\d{4}

 4자리의 숫자



Source 04) RegularExpressionEx04.java
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
package regularExpressionEx;
 
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
import javax.swing.plaf.basic.BasicInternalFrameTitlePane.MaximizeAction;
 
public class RegularExpressionEx04 {
 
    public static void main(String[] args) {
        String source = "A broken hand works, but not a broken heart.";
        String pattern = "broken";
        StringBuffer sb = new StringBuffer();
 
        Pattern p = Pattern.compile(pattern);
        Matcher m = p.matcher(source);
        System.out.println("source : " + source);
 
        int i = 0;
        while (m.find()) {
            System.out.println(+++ "번째 매칭 : " + m.start() + "~" + m.end());
            // broken를 drunken으로 치환하여 sb에 저장한다.
            m.appendReplacement(sb, "drunken");
        }
 
        m.appendTail(sb);
        System.out.println("Replacement : " + i);
        System.out.println("result :" + sb.toString());
    }
}
cs

Result)
1
2
3
4
5
source : A broken hand works, but not a broken heart.
1번째 매칭 : 2~8
2번째 매칭 : 31~37
Replacement : 2
result :A drunken hand works, but not a drunken heart.
cs

Matcher의 find()로 정규식과 일치하는 부분을 찾으면, 그 위치를 start()와 end()로 알아낼 수 있고,
appendReplacement(StringBuffer sb, String replacement)를 이용해서 원하는 문자열(replacement)로 치환할 수 있다.
치환된 결과는 StringBuffer인 sb에 저장된다.



출처 및 참고자료 : JAVA의정석(남궁성 저)

반응형

공유

댓글