자바(java) 정규표현식(regex) 과 활용
자바 정규표현식을 알아두면 현업에서도 많이 쓰일 수 있다.
실제적으로 안드로이드 프로그래밍하면서 딥링크나, 배너만들 때 많이 이용하게 된다.
물론 전화번호, 이메일, 비밀번호 관련 유효성에도 많이 쓰인다.
정규표현식에도 역사와 표준이 있는데, 그렇게 깊게 들어가지는 않고 자바에서 바로 사용할 수 있는 정규표현식을 정리하려고 한다.
이 문서는 지속적으로 발전될 것이며 시시각각 수정될 것이다.
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@