Published 2022. 11. 25. 18:30

정규표현식(regex)

정규표현식(Regular expressions)은 줄여서 Regex라고 합니다. Regex는 문자열에 어떤 패턴의 문자들이 있는지 찾는데 도움을 줍니다.

이 글은 Regex의 패턴과 사용방법 위주로 정리하였습니다. Regex는 대부분 알고 있지만, 적용할 표현들이 헷갈렸다면 이 글을 참고하시면서 패턴을 작성해보세요.

 

 

Metacharacters

Metacharacters는 Regex의 패턴에서 어떤 문자가 특별한 의미를 갖는 것을 말합니다. 예를 들어, \d는 0에서 9사이의 숫자를 의미합니다.

 

Regular Expression Description
. 어떤 문자 1개를 의미
^regex ^ 다음 regex로 line을 시작하는지
regex$ $ 앞의 regex가 line의 마지막으로 끝나는지
[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 단어의 경계(공백)를 찾습니다
@Test
public void ex1() {
    String pattern = "ab.";
    assertFalse("ab".matches(pattern));
    assertTrue("abc".matches(pattern));

    pattern = "ab\\s\\S";
    assertFalse("ab  ".matches(pattern));
    assertTrue("ab c".matches(pattern));
}
@Test
public void ex2() {
  String result;
  result = "The cat sat on the mat.".replaceAll("[Tt]he", "*");
  System.out.println(result);

  result = "The cat sat on the mat.".replaceAll("^[Tt]he", "*");
  System.out.println(result);
}

* cat sat on * mat.
* cat sat on the mat.

 

@Test
public void ex3() {
    String result;
    result = "The cat sat on the mat. and the cat".replaceAll("cat", "*");
    System.out.println(result);

    result = "The cat sat on the mat. and the cat".replaceAll("cat$", "*");
    System.out.println(result);
}
The * sat on the mat. and the *
The cat sat on the mat. and the *
@Test
public void ex15() {
    String result;
    result = "This island is beautiful.".replaceAll("is", "*");
    System.out.println(result);

    result = "This island is beautiful.".replaceAll("\\bis\\b", "*");
    System.out.println(result);
}

Th* *land * beautiful.
This island * beautiful.
@Test
public void ex4() {
    String pattern = "[abc][vz]";
    assertTrue("av".matches(pattern));
    assertFalse("ac".matches(pattern));

    pattern = "Ex_[a-g1-5]";
    assertTrue("Ex_g".matches(pattern));
    assertFalse("Ex_6".matches(pattern));
}

자바는 \를 표현하려면 \\로 입력해야 합니다. 가독성이 떨어지는 면이 있습니다.

@Test
public void ex5() {
    String pattern = "\\d\\D";
    assertTrue("1a".matches(pattern));
    assertFalse("a1".matches(pattern));

    pattern = "\\d\\s\\D";
    assertTrue("1 a".matches(pattern));

    pattern = "\\d\\s\\S\\D";
    assertTrue("1 1a".matches(pattern));

    pattern = "\\w\\W";
    assertTrue("1 ".matches(pattern));
}

 

 

 

 

Quantifiers

Quantifiers는 요소들을 얼마나 반복시킬지 정의합니다.

Regular Expression Description
* 0회 이상 반복
+ 1회 이상 반복
? 0 또는 1회만
{X} X회 이상 반복
{X,Y} X~Y 사이의 수만큼 반복
*? 가장 적게 일치하는 패턴을 찾음
@Test
public void ex6() {
    String pattern = "a*[0-9]*";
    assertTrue("aaa123".matches(pattern));
    assertTrue("aaa".matches(pattern));

    pattern = "a*[0-9]+";
    assertTrue("aaa123".matches(pattern));
    assertFalse("aaa".matches(pattern));
}
@Test
public void ex7() {
    String pattern = "a*[0-9]?";
    assertTrue("aaa".matches(pattern));
    assertFalse("aaa12".matches(pattern));

    pattern = "a*[0-9]{0,1}";
    assertTrue("aaa".matches(pattern));
    assertFalse("aaa12".matches(pattern));
}

 

 

 

 

Grouping

"1 character + whitespaces + 1 character"을 의미합니다. 그룹은 3개로 나누었습니다.

@Test
public void ex8() {
    String pattern = "(\\w)(\\s+)([\\w])";
    System.out.println("Hello     World".replaceAll(pattern, "-"));

    pattern = "(\\w)(\\s+)([\\w])";
    System.out.println("Hello     World".replaceAll(pattern, "$1-$3"));
}

Hell-orld
Hello-World

 

 

 

 

 

Regex를 지원하는 String 메소드

Method Description
String.matches(regex) String이 regex와 일치하면 true 리턴
String.split(regex) regex와 일치하는 것을 기준으로 String을 분리하여 배열로 리턴
String.replaceFirst(regex, replacement) regex와 가장 먼저 일치하는 것을 replacement로 변환
String.replaceAll(regex, replacement) regex와 일치하는 모든 것을 replacement로 변환

 

@Test
public void ex9() {
    String pattern = "a*[0-9]*";
    assertTrue("aaa123".matches(pattern));

    pattern = "\\s";
    String arr[] = "Hello World Java Regex".split(pattern);
    System.out.println(Arrays.asList(arr));

    pattern = "Hello";
    System.out.println("Hello World Hello World ".replaceFirst(pattern, "Regex"));

    pattern = "Hello";
    System.out.println("Hello World Hello World ".replaceAll(pattern, "Regex"));
}

[Hello, World, Java, Regex]
Regex World Hello World
Regex World Regex World

 

 

 

Pattern

Regex는 "\d"와 같이 String으로 표현할 수 있습니다. Pattern은 컴파일된 Regex라고 표현합니다.

다음과 같이 Regex String을 컴파일하여 Pattern이라는 객체로 만듭니다.

Pattern pattern = Pattern.compile("\\bcat\\b");

 

 

 

Matcher

@Test
public void ex10() {
    Pattern pattern = Pattern.compile("\\bcat\\b");
    Matcher matcher = pattern.matcher("cat cat cat cattie cat");
    int count = 0;
    while(matcher.find()) {
        count++;
        System.out.println("Match number " + count);
        System.out.println("group(): " + matcher.group());
        System.out.println("start(): " + matcher.start());
        System.out.println("end(): " + matcher.end());
    }
}


Match number 1
group(): cat
start(): 0
end(): 3
Match number 2
group(): cat
start(): 4
end(): 7
Match number 3
group(): cat
start(): 8
end(): 11
Match number 4
group(): cat
start(): 19
end(): 22

 

 

 

숫자 패턴 찾기

@Test
public void ex11() {
    Pattern pattern = Pattern.compile("\\d{3}-\\d{5}");
    Matcher matcher = pattern.matcher("123-45678");
    assertTrue(matcher.find());
}

 

 

 

Backreferences

Regex에서 이전에 사용된 subpattern을 참조하는 것도 가능합니다. 이것을 Backreferences라고 합니다.

Backreferences는 \n으로 표현합니다. 예를 들어, \1는 첫번째 subpattern이며, \2는 두번째 subpattern입니다.

아래 예제에서 \1은 첫번째 subpattern (..)을 의미합니다.

@Test
public void ex12() {
    Pattern pattern = Pattern.compile("c(..) s\\1");
    Matcher matcher = pattern.matcher("The cat sat on the mat");
    assertTrue(matcher.find());
}

 

Replace

@Test
public void ex13() {
    String result;
    Pattern p = Pattern.compile("dog");
    Matcher m = p.matcher("The dog says meow. All dogs say meow.");
    System.out.println(m.replaceAll("cat"));

    result = "The cat sat on the mat.".replaceAll("at[.]", "*");
    System.out.println(result);

    result = "The cat sat on the mat.".replaceAll("at[.]?", "*");
    System.out.println(result);

    result = "The cat sat on the mat.".replaceAll("[a-z]+", "*");
    System.out.println(result);
}

The cat says meow. All cats say meow.
The cat sat on the m*
The c* s* on the m*
T* * * * * *.

 

 

+? 또는 *? 의 예제

?가 단독으로 사용되면 0 또는 1회라는 의미입니다. 하지만 +, * 등과 함께 사용되면 가장 적은 조건으로 매칭되는 문자열을 찾는다는 의미입니다.

@Test
public void ex14() {
    String result;
    result = "The cat sat on the mat.".replaceAll("c.+t", "*");
    System.out.println(result);

    result = "The cat sat on the mat.".replaceAll("c.+?t", "*");
    System.out.println(result);
}

The *.
The * sat on the mat.
복사했습니다!