자바에서 정규표현식(Regular Expression)을 사용하는 방법에 대해서 알아보겠습니다.

1. 정규표현식(Regular Expression)

정규표현식, 정규식은 어떤 패턴을 갖고 있는 문자열 집합을 표현하는 방법입니다.

기본적으로 아래 두가지 과정을 거쳐, 문자열에서 정규표현식과 일치하는 패턴을 찾을 수 있습니다.

  • 패턴 생성
  • 패턴 매칭

2. 패턴 생성 방법

Pattern.compile(regex)는 regex에 대한 Pattern 객체를 생성합니다. Pattern 객체로 문자열 매칭을 하여 regex와 일치하는 문자열을 찾을 수 있습니다.

String regexPattern = "regular-expression";
Pattern pattern = Pattern.compile(regexPattern);

3. 패턴 매칭 방법

기본적으로 패턴 매칭은 Matcher를 이용합니다. Matcher는 Pattern.matcher(string)으로 생성할 수 있습니다. 이렇게 생성된 Matcher는 Regex와 일치하는 문자열 정보들을 갖고 있습니다. find(), group() 등의 함수를 이용하여 패턴 정보를 얻을 수 있습니다.

Pattern pattern = Pattern.compile("\\bdog\\b");
Matcher matcher = pattern.matcher("dog dog dog doggy dog");

// 일치하는 문자열 찾기
if (matcher.find()) {
    String matchedText = matcher.group(); // 매칭된 문자열
}

아래 예제는 "dog dog dog doggy dog" 문자열에서 "\\bdog\\b" 패턴의 문자열을 모두 찾는 예제입니다.

  • Matcher.find() : 패턴과 일치하는 문자열을 찾고 문자열이 있으면 true를 리턴, 일치하는 문자열이 2개 이상일 때, Iterator처럼 while문을 사용하여 여러번 탐색할 수 있음. 모든 패턴을 찾으면 false를 리턴하면서 while문이 종료됨
  • Matcher.group() : 매칭된 문자열 리턴
  • Matcher.start() : 매칭된 문자열의 시작 위치(Index) 리턴
  • Matcher.end() : 매칭된 문자열의 끝 바로 다음 위치(Index) 리턴
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Example {

    public static void main(String[] args) {

        Pattern pattern = Pattern.compile("\\bdog\\b");
        Matcher matcher = pattern.matcher("dog dog dog doggy dog");
        int index = 0;
        while (matcher.find()) {
            System.out.println("Match index: " + index);
            System.out.println("group(): " + matcher.group());
            System.out.println("start(): " + matcher.start());
            System.out.println("end(): " + matcher.end());
            System.out.println("");
            index++;
        }
    }
}

Output:

Match index: 0
group(): dog
start(): 0
end(): 3

Match index: 1
group(): dog
start(): 4
end(): 7

Match index: 2
group(): dog
start(): 8
end(): 11

Match index: 3
group(): dog
start(): 18
end(): 21

4. 문자열 패턴 매칭

String.matches(pattern)은 String이 pattern과 일치할 때 true를 리턴합니다.

위에서 소개한 Matcher와 Pattern 객체를 사용하지 않고, 간단히 특정 패턴의 문자열이 맞는지 확인할 수 있습니다.

String pattern = "ab.+";

System.out.println("1) " + "ab".matches(pattern));
System.out.println("2) " + "abc".matches(pattern));
System.out.println("3) " + "abcccc".matches(pattern));

Output:

1) false
2) true
3) true

5. String.replaceAll()의 정규표현식

String.replaceAll(regex, replacement)는 문자열에서 regex와 일치하는 모든 문자열을 replacement로 교체합니다.

  • 아래 예제는 HTML 태그를 찾아서 빈문자열로 변환하여 제거
String htmlText = "<p>이 문장은 HTML 태그를 포함합니다.</p>";
String result = htmlText.replaceAll("<[^>]*>", "");
System.out.println(result);

Output:

이 문장은 HTML 태그를 포함합니다.

다음은 replaceAll()에서 group을 이용하는 예제입니다.

  • replaceAll(".*(" + phonePattern + ").*", "$1")는 패턴을 포함하는 모든 문자열을 의미하는데, regex의 (..) 부분이 group이 됩니다. replacement의 "$1"는 일치하는 문자열을 첫번째 group과 교체하라는 의미로, group을 제외한 모든 문자열이 제거됩니다.
String phoneNumber = "문의사항은 123-456-7890으로 연락주세요.";
String phonePattern = "\\d{3}-\\d{3}-\\d{4}";

String result = phoneNumber.replaceAll(".*(" + phonePattern + ").*", "$1");
System.out.println(result);

Output:

123-456-7890

6. String.split()의 정규표현식

split()과 정규표현식을 이용하여 문자열을 분리할 수 있습니다.

str.split(regex)는 str에서 regex와 일치하는 문자열을 분리하여 String[]로 리턴합니다.

String sentence = "이것은, 쉼표로 구분된, 문장입니다.";
String[] parts = sentence.split(",");
System.out.println(Arrays.asList(parts));

Output:

[이것은,  쉼표로 구분된,  문장입니다.]

7. 다른 정규표현식 예제

지금까지 기본적으로 정규표현식 패턴으로 일치하는 문자열을 찾는 방법에 대해서 알아보았습니다.

다양한 패턴 예제들을 확인해보겠습니다.

주민등록번호 찾기

문자열에서 주민등록번호를 추출하는 예제입니다.

  • \\d : 숫자
  • {6} : 앞의 문자 6번 반복
  • \\d{7} : 숫자 7번 반복
String text = "주민등록번호는 123456-1234567과 987654-9876543입니다.";
String ssnPattern = "\\d{6}-\\d{7}";
Pattern pattern = Pattern.compile(ssnPattern);
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
    System.out.println("주민등록번호: " + matcher.group());
}

Output:

주민등록번호: 123456-1234567
주민등록번호: 987654-9876543

유효한 이름 체크

이름이 유효한지 체크하기 위해, 문자열의 첫번째가 대문자이고 나머지는 소문자인지 확인합니다.

  • ^ : 문자열 시작
  • [A-Z] : 대문자 알파벳 문자 1개
  • [a-z] : 소문자 알파벳 1개 이상
  • $ : 문자열 끝
String name = "John";
String namePattern = "^[A-Z][a-z]+$";
boolean isNameValid = name.matches(namePattern);
System.out.println(isNameValid);

Output:

true

URL 찾기

아래 예제는 문자열에서 URL을 찾습니다.

  • ? : 앞의 문자가 0개 또는 1개
  • s? : s가 0개 또는 1개
  • \\S : 공백 문자가 아닌 문자
  • + : 앞의 문자가 1개 이상
String text = "웹사이트는 https://www.example.com 입니다.";
String urlPattern = "https?://\\S+";
Pattern pattern = Pattern.compile(urlPattern);
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
    System.out.println("URL: " + matcher.group());
}

Output:

URL: https://www.example.com

8. 정규표현식 문법

다양한 정규표현식 문법을 정리하였습니다. 정규표현식을 보실 때 참고하시면 됩니다.

패턴에 대한 표현식

Regular Expression Description
. 어떤 문자 1개를 의미
^ 문자열이 시작
$ 문자열의 끝
[abc] a, b, c 중의 문자 1개
[abc][vz] a, b, c 중에 문자 1개와 v, z 중에 문자 1개의 조합
[^abc] a, b, c를 제외한 문자 1개
[a-d1-7] ad, 17 사이의 문자 1개
X|Z X 또는 Z
\d 0~9 사이의 숫자, [0-9]와 동일
\D 숫자가 아닌 어떤 문자, [^0-9]와 동일
\s whitespace 1개, [\t\n\x0b\r\f]와 동일
\S whitespace를 제외한 문자
\w Alphanumeric(alphabet, 숫자) 문자, [a-zA-Z_0-9]와 동일
\W Alphanumeric을 제외한 문자(whitespace 등)
\S+ whitespace를 제외한 여러 문자
\b 단어의 경계(공백)를 찾습니다

반복에 대한 표현식

Regular Expression Description
* 0회 이상 반복
+ 1회 이상 반복
? 0 또는 1회만
{X} X회 이상 반복
{X,Y} X~Y 사이의 수만큼 반복
*? 가장 적게 일치하는 패턴을 찾음