과거의 기록

자바(java) 정규표현식(regex) 과 활용

이병록 2016. 12. 3. 07:18

자바 정규표현식을 알아두면 현업에서도 많이 쓰일 수 있다.

 

실제적으로 안드로이드 프로그래밍하면서 딥링크나, 배너만들 때 많이 이용하게 된다.

 

물론 전화번호, 이메일, 비밀번호 관련 유효성에도 많이 쓰인다.

 

정규표현식에도 역사와 표준이 있는데, 그렇게 깊게 들어가지는 않고 자바에서 바로 사용할 수 있는 정규표현식을 정리하려고 한다.

 

이 문서는 지속적으로 발전될 것이며 시시각각 수정될 것이다.

 

 

 

1. 메타 문자

 

메타 문자는 하나의 문자를 의미하며, 패턴을 만들 때 각 하나의 문자를 의미한다.

 

 

 .

 모든 문자를 포함한다.

 |

 OR를 뜻하며 연산자 기준 왼쪽 오른쪽 각각 포함하거나 다 포함할 경우이다.

 []

 문자 집합 구성 중 하나의 문자를 포함 해야한다.

 [^]

 문자 집합에서 해당 문자열을 제외한다.

 -

 문자 집합의 범위를 지정한다.

 

\ 라는 특수한 문자가 있는데 이 부분은 이 문자 다음에 오는 문자를 이스케이프 처리한다.

 

메타문자는 하나로만 의미가 있기는 힘들다. 수량자와 함께할 때 많이 쓰인다.

 

예제)

String test1 = "a";
String regexTest1 = "^a$";
String regexTest2 = "^.$";
String regexTest3 = "^[a-z]$";
String regexTest4 = "^[abc]$";
String regexTest5 = "^[^a]$";
        
        
System.out.println(String.format("regex: %s / text : %s / result : %s", regexTest1, test1, test1.matches(regexTest1)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regexTest2, test1, test1.matches(regexTest2)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regexTest3, test1, test1.matches(regexTest3)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regexTest4, test1, test1.matches(regexTest4)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regexTest5, test1, test1.matches(regexTest5)));

 

결과)

regex: ^a$ / text : a / result : true
regex: ^.$ / text : a / result : true
regex: ^[a-z]$ / text : a / result : true
regex: ^[abc]$ / text : a / result : true
regex: ^[^a]$ / text : a / result : false

 

 

2. 수량자 

수량자에는 탐욕적 수량자게으른 수량자가 있는데, 이 부분은 예제로 확인하면 좀 더 이해가 쉬울 것이다.

 

1) 탐욕적 수량자

 +

 앞의 문자가 하나이상 나와야 한다.

 *

 앞의 문자가 0개 이상 나와야 한다.

 ?

 앞의 문자가 0또는 1개가 나와야 한다.

 {n}

 앞의 문자가 n번 이어야 한다.

 {n, m}

 앞의 문자가 n 이상 m번 이하 이어야 한다.

 {n,}

 앞의 문자가 n번 이상 이어야 한다.

 

 

2) 게으른 수량자

 

게으른 수량자는 탐욕적 수량자에 ?를 붙이면 게으른 수량자가 된다.

보통 게으른 수량자는 패턴을 통해 검색결과를 찾을 때 유용하다.

 

 +?

 앞의 문자가 하나이상 나와야 한다.

 *?

 앞의 문자가 0개 이상 나와야 한다.

 {n,}?

 앞의 문자가 n번 이상 이어야 한다.

 

 

 

예제)

 

String text1 = "baa";
String text2 = "ba";
String text3 = "b";
        
System.out.println("----------------------------------------------------------------------");
        
String regex = "^ba+$";
System.out.println(String.format("regex: %s / text : %s / result : %s", regex, text1, text1.matches(regex)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex, text2, text2.matches(regex)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex, text3, text3.matches(regex)));
        
System.out.println("----------------------------------------------------------------------");
String regex2 = "^ba*$";
System.out.println(String.format("regex: %s / text : %s / result : %s", regex2, text1, text1.matches(regex2)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex2, text2, text2.matches(regex2)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex2, text3, text3.matches(regex2)));
        
System.out.println("----------------------------------------------------------------------");
String regex3 = "^ba.$";
System.out.println(String.format("regex: %s / text : %s / result : %s", regex3, text1, text1.matches(regex3)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex3, text2, text2.matches(regex3)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex3, text3, text3.matches(regex3)));
        
System.out.println("----------------------------------------------------------------------");
String regex4 = "^ba?$";
System.out.println(String.format("regex: %s / text : %s / result : %s", regex4, text1, text1.matches(regex4)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex4, text2, text2.matches(regex4)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex4, text3, text3.matches(regex4)));

 

 

 

결과)

----------------------------------------------------------------------
regex: ^ba+$ / text : baa / result : true
regex: ^ba+$ / text : ba / result : true
regex: ^ba+$ / text : b / result : false
----------------------------------------------------------------------
regex: ^ba*$ / text : baa / result : true
regex: ^ba*$ / text : ba / result : true
regex: ^ba*$ / text : b / result : true
----------------------------------------------------------------------
regex: ^ba.$ / text : baa / result : true
regex: ^ba.$ / text : ba / result : false
regex: ^ba.$ / text : b / result : false
----------------------------------------------------------------------
regex: ^ba?$ / text : baa / result : false
regex: ^ba?$ / text : ba / result : true
regex: ^ba?$ / text : b / result : true

 

 

 


 

 

3. 메타 문자와 수량자의 결합

 

메타문자와 수량자가 결합해서 패턴을 만들 수 있다.

 

예제)

String text1 = "baa";
String text2 = "ba";
String text3 = "b";

System.out.println("----------------------------------------------------------------------");

String regex5 = "^[a-z]a$";
System.out.println(String.format("regex: %s / text : %s / result : %s", regex5, text1, text1.matches(regex5)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex5, text2, text2.matches(regex5)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex5, text3, text3.matches(regex5)));
        
System.out.println("----------------------------------------------------------------------");
String regex6 = "^[A-Z]a$";
System.out.println(String.format("regex: %s / text : %s / result : %s", regex6, text1, text1.matches(regex6)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex6, text2, text2.matches(regex6)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex6, text3, text3.matches(regex6)));
        
System.out.println("----------------------------------------------------------------------");
String regex7 = "^[A-Z]a$";
System.out.println(String.format("regex: %s / text : %s / result : %s", regex7, text1, text1.matches(regex7)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex7, text2, text2.matches(regex7)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex7, text3, text3.matches(regex7)));
        
        
String text4 = "aa";
String text5 = "ba";
String text6 = "baa";
        
System.out.println("----------------------------------------------------------------------");
String regex8 = "^(a|b)a$";
System.out.println(String.format("regex: %s / text : %s / result : %s", regex8, text4, text4.matches(regex8)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex8, text5, text5.matches(regex8)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex8, text6, text6.matches(regex8)));
        
System.out.println("----------------------------------------------------------------------");
String regex9 = "^(a|b)a+$";
System.out.println(String.format("regex: %s / text : %s / result : %s", regex9, text4, text4.matches(regex9)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex9, text5, text5.matches(regex9)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex9, text6, text6.matches(regex9)));
        
System.out.println("----------------------------------------------------------------------");
String regex10 = "^[^b]a+$";
System.out.println(String.format("regex: %s / text : %s / result : %s", regex10, text4, text4.matches(regex10)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex10, text5, text5.matches(regex10)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex10, text6, text6.matches(regex10)));
        
System.out.println("----------------------------------------------------------------------");
String regex11 = "^(ba)a*$";
System.out.println(String.format("regex: %s / text : %s / result : %s", regex11, text4, text4.matches(regex11)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex11, text5, text5.matches(regex11)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex11, text6, text6.matches(regex11)));
        
        
String text7 = "baa";
String text8 = "baaa";
String text9 = "baaaa";
        
System.out.println("----------------------------------------------------------------------");
String regex12 = "^ba{3}$";
System.out.println(String.format("regex: %s / text : %s / result : %s", regex12, text7, text7.matches(regex12)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex12, text8, text8.matches(regex12)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex12, text9, text9.matches(regex12)));
        
System.out.println("----------------------------------------------------------------------");
String regex13 = "^ba{3,}$";
System.out.println(String.format("regex: %s / text : %s / result : %s", regex13, text7, text7.matches(regex13)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex13, text8, text8.matches(regex13)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex13, text9, text9.matches(regex13)));
        
System.out.println("----------------------------------------------------------------------");
String regex14 = "^ba{2,3}$";
System.out.println(String.format("regex: %s / text : %s / result : %s", regex14, text7, text7.matches(regex14)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex14, text8, text8.matches(regex14)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex14, text9, text9.matches(regex14)));
 

 

결과)

 

----------------------------------------------------------------------
regex: ^[a-z]a$ / text : baa / result : false
regex: ^[a-z]a$ / text : ba / result : true
regex: ^[a-z]a$ / text : b / result : false
----------------------------------------------------------------------
regex: ^[A-Z]a$ / text : baa / result : false
regex: ^[A-Z]a$ / text : ba / result : false
regex: ^[A-Z]a$ / text : b / result : false
----------------------------------------------------------------------
regex: ^[A-Z]a$ / text : baa / result : false
regex: ^[A-Z]a$ / text : ba / result : false
regex: ^[A-Z]a$ / text : b / result : false
----------------------------------------------------------------------
regex: ^(a|b)a$ / text : aa / result : true
regex: ^(a|b)a$ / text : ba / result : true
regex: ^(a|b)a$ / text : baa / result : false
----------------------------------------------------------------------
regex: ^(a|b)a+$ / text : aa / result : true
regex: ^(a|b)a+$ / text : ba / result : true
regex: ^(a|b)a+$ / text : baa / result : true
----------------------------------------------------------------------
regex: ^[^b]a+$ / text : aa / result : true
regex: ^[^b]a+$ / text : ba / result : false
regex: ^[^b]a+$ / text : baa / result : false
----------------------------------------------------------------------
regex: ^(ba)a*$ / text : aa / result : false
regex: ^(ba)a*$ / text : ba / result : true
regex: ^(ba)a*$ / text : baa / result : true
----------------------------------------------------------------------
regex: ^ba{3}$ / text : baa / result : false
regex: ^ba{3}$ / text : baaa / result : true
regex: ^ba{3}$ / text : baaaa / result : false
----------------------------------------------------------------------
regex: ^ba{3,}$ / text : baa / result : false
regex: ^ba{3,}$ / text : baaa / result : true
regex: ^ba{3,}$ / text : baaaa / result : true
----------------------------------------------------------------------
regex: ^ba{2,3}$ / text : baa / result : true
regex: ^ba{2,3}$ / text : baaa / result : true
regex: ^ba{2,3}$ / text : baaaa / result : false
 

 

 


 

4. 특수문자

 

보통 쓰이는 이스케이프 문자도 포함된다.

 

 [\b]

 백스페이스

 \d

 [0-9]와 같다.

 \D

 [0-9]를 제외 [^0-9]와 같다.

 \w

 [a-zA-Z0-9]와 같다.

 \W

 [^a-zA-Z0-9]와 같다.

 \n

 줄바꿈

 \r

 캐리지 리턴

 \t

 탭

 


5. 패턴

 

[ ]는 해당 문자의 범위를 나타내지만 ( )는 패턴 자체를 나타낸다.

만약에 '(' 나 ')' 를 찾으려면 '\('  '\)'를 써야한다.

 

 (패턴)

 한 단위 문자의 패턴을 정의한다.

 문자(=?패턴)

 문자 다음에 항상 =? 다음의 문자가 패턴에 맞아야한다. 

 

 

 

예제)

 

String test2 = "hardtest";
String test3 = "harddisk";
String test4 = "hardhost";
        
String regexTest6 = "^hard(=?test)$";
String regexTest7 = "^hard(test|disk)$";
        
System.out.println("----------------------------------------------------------------------");
System.out.println(String.format("regex: %s / text : %s / result : %s", regexTest6, test2, test2.matches(regexTest6)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regexTest6, test3, test3.matches(regexTest6)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regexTest6, test4, test4.matches(regexTest6)));
        
System.out.println(String.format("regex: %s / text : %s / result : %s", regexTest7, test2, test2.matches(regexTest7)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regexTest7, test3, test3.matches(regexTest7)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regexTest7, test4, test4.matches(regexTest7)));
 

 

 

결과)

----------------------------------------------------------------------
regex: ^hard(=?test)$ / text : hardtest / result : true
regex: ^hard(=?test)$ / text : harddisk / result : false
regex: ^hard(=?test)$ / text : hardhost / result : false
regex: ^hard(test|disk)$ / text : hardtest / result : true
regex: ^hard(test|disk)$ / text : harddisk / result : true
regex: ^hard(test|disk)$ / text : hardhost / result : false
 

 

6. 정규표현식의 활용

 

예제)

String text10 = "t@n.com";
String text11 = "t@vas.com";
String text12 = "@vas.com";
String text13 = "t@.com";
String text14 = "t@d.";
String text15 = "td.com";
String text16 = "td@.com";
String text17 = "@.com";
        
        
System.out.println("----------------------------------------------------------------------");
String regex15 = "^\\w+@\\w+\\.\\w+$";
System.out.println(String.format("regex: %s / text : %s / result : %s", regex15, text10, text10.matches(regex15)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex15, text11, text11.matches(regex15)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex15, text12, text12.matches(regex15)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex15, text13, text13.matches(regex15)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex15, text14, text14.matches(regex15)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex15, text15, text15.matches(regex15)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex15, text16, text16.matches(regex15)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex15, text17, text17.matches(regex15)));
        
        
String text18 = "abcde!zx";
String text19 = "Abcdezx";
String text20 = "Abcde*!zx";
String text21 = "abcdezx";
String text22 = "ab!Ace";
String text23 = "abcdefghijk!mnop";
        
System.out.println("----------------------------------------------------------------------");
String regex16 = "^(?=.*\\w*)(?=.*[!@#$%^&*]+).{8,10}$";
System.out.println(String.format("regex: %s / text : %s / result : %s", regex16, text18, text18.matches(regex16)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex16, text19, text19.matches(regex16)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex16, text20, text20.matches(regex16)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex16, text21, text21.matches(regex16)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex16, text22, text22.matches(regex16)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex16, text23, text23.matches(regex16)));
        
String text24 = "01012345678";
String text25 = "010-1234-5678";
String text26 = "010-234-1678";
String text27 = "010-2341-678";
String text28 = "010-1234567";
String text29 = "010-12345678";
        
System.out.println("----------------------------------------------------------------------");
String regex17 = "^(010|019|016|011)-?(\\d{3,4})-?(\\d{4})$";
System.out.println(String.format("regex: %s / text : %s / result : %s", regex17, text24, text24.matches(regex17)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex17, text25, text25.matches(regex17)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex17, text26, text26.matches(regex17)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex17, text27, text27.matches(regex17)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex17, text28, text28.matches(regex17)));
System.out.println(String.format("regex: %s / text : %s / result : %s", regex17, text29, text29.matches(regex17)));
                
        
String text30 = "hi my name is @name, roka@ what is your name? My name is @name, hahata@";
        
String regex18 = "@.*@";
String regex19 = "@.*?@";
Pattern pattern1 = Pattern.compile(regex18);
Matcher matcher1 = pattern1.matcher(text30);

while(matcher1.find()) {
    System.out.println(text30.substring(matcher1.start(), matcher1.end()));
}
        
Pattern pattern2 = Pattern.compile(regex19);
Matcher matcher2 = pattern2.matcher(text30);

while(matcher2.find()) {
    System.out.println(text30.substring(matcher2.start(), matcher2.end()));
}

 

결과)

----------------------------------------------------------------------
regex: ^\w+@\w+\.\w+$ / text : t@n.com / result : true
regex: ^\w+@\w+\.\w+$ / text : t@vas.com / result : true
regex: ^\w+@\w+\.\w+$ / text : @vas.com / result : false
regex: ^\w+@\w+\.\w+$ / text : t@.com / result : false
regex: ^\w+@\w+\.\w+$ / text : t@d. / result : false
regex: ^\w+@\w+\.\w+$ / text : td.com / result : false
regex: ^\w+@\w+\.\w+$ / text : td@.com / result : false
regex: ^\w+@\w+\.\w+$ / text : @.com / result : false
----------------------------------------------------------------------
regex: ^(?=.*\w*)(?=.*[!@#$%^&*]+).{8,10}$ / text : abcde!zx / result : true
regex: ^(?=.*\w*)(?=.*[!@#$%^&*]+).{8,10}$ / text : Abcdezx / result : false
regex: ^(?=.*\w*)(?=.*[!@#$%^&*]+).{8,10}$ / text : Abcde*!zx / result : true
regex: ^(?=.*\w*)(?=.*[!@#$%^&*]+).{8,10}$ / text : abcdezx / result : false
regex: ^(?=.*\w*)(?=.*[!@#$%^&*]+).{8,10}$ / text : ab!Ace / result : false
regex: ^(?=.*\w*)(?=.*[!@#$%^&*]+).{8,10}$ / text : abcdefghijk!mnop / result : false
----------------------------------------------------------------------
regex: ^(010|019|016|011)-?(\d{3,4})-?(\d{4})$ / text : 01012345678 / result : true
regex: ^(010|019|016|011)-?(\d{3,4})-?(\d{4})$ / text : 010-1234-5678 / result : true
regex: ^(010|019|016|011)-?(\d{3,4})-?(\d{4})$ / text : 010-234-1678 / result : true
regex: ^(010|019|016|011)-?(\d{3,4})-?(\d{4})$ / text : 010-2341-678 / result : false
regex: ^(010|019|016|011)-?(\d{3,4})-?(\d{4})$ / text : 010-1234567 / result : true
regex: ^(010|019|016|011)-?(\d{3,4})-?(\d{4})$ / text : 010-12345678 / result : true
@name, roka@ what is your name? My name is @name, hahata@
@name, roka@
@name, hahata@