본문 바로가기

JAVA 개인공부

[JAVA] 정규표현식(regex) [2/2]

수량자(Quantifiers)

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

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

 

*은 * 앞의 요소가 0회 이상 반복되는 것을 의미합니다.

+는 1회 이상 반복되는 것을 의미합니다.

이것은 요소가 1개도 없으면 패턴과 일치하지 않는다는 의미입니다.

 

public void Example() {
    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));
}

 

?는 요소가 0회 또는 1회만 반복되는 것을 의미합니다.

 

{X, Y}는 X ~ Y 사이의 수만큼 반복된다는 것을 의미하며,

위에서 문자열 1개로 처리했던 것을 모두 표현할 수 있습니다.

 

아래 예제에서 {0, 1}은 ?와 동일한 의미입니다.

 

public void Example() {
    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처럼 $ 다음에 그룹의 번호를 입력합니다.

패턴에서 가장 왼쪽 그룹이 1번으로 시작합니다.

 

아래 예제의 패턴은 "1 character + whitespaces + 1 character"을 의미합니다.

그룹은 3개로 나누었습니다.

그룹 1은 Hello, 그룹 2는 whitespaces, 그룹 3은 World입니다.

public void Example() {
    String pattern = "(\\w)(\\s+)([\\w])";
    System.out.println("Hello     World".repalceAll(patternm, "-");
    
    pattern = "(\\w)(\\s+)([\\w])";
    System.out.println("Hello     World".replaceAll(pattern, "$1-$3"));
}

// 실행결과
Hell-orld
Hello-World

 

위의 예제에서 패턴과 일치하는 것은 "o W"이며, 첫 번째 예제는 일치하는 문자열을 "-"로 변환했습니다.

 

두 번째는 replacement에는 "$1-$3"을 입력하였는데, 이것은 Format과 유사합니다.

그룹 1과 그룹 3에 해당하는 내용으로 변환이 됩니다.

 

Regex를 지원하는 String 메소드

String 클래스는 Regex를 지원하는 메소드들이 있습니다.

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로 변환

 

위에서 소개한 메소드들에 대한 예제입니다.

 

public void Example() {
    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("Hellow World Hello World ".replaceFirst(pattern, "Regex"));
    
    pattern ="Hello";
    System.out.println("Hellow World Hello World ".replaceAll(pattern, "Regex"));
}

// 실행결과
[Hello, World, Java, Regex]
Regex World Hello World
Regex World Regex World

 

다양한 예제

숫자 패턴 찾기

public void Example() {
    Pattern pattern = Pattern.comile("\\d{3}-\\d{5}");
    Matcher matcher = pattern.matcher("123-45678");
    assertTrue(matcher.find());
}

 

Backrefernces

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

이것을 Backreferences라고 합니다.

 

Backreferences는 \n으로 표현합니다.

예를 들어, \1는 첫 번째 subpattern이며, \2는 두 번째 subpattern입니다.

 

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

 

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

 

중복된 단어 패턴 찾기

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

따라서 동일한 단어가 연달아 오는 String은 이 패턴과 일치하게 됩니다.

 

public void Example() {
    Pattern pattern = Pattern.compile("\\b(\\w+)\\s+\\1\\b");
    Matcher matcher = pattern.matcher("hello world world");
    assertTrue(matcher.find());
}

 

Replace

Replace와 관련된 예제입니다.

 

public void Example() {
    String result;
    Pattern p = Patter.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회라는 의미입니다.

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

 

아래 예제에서 +만 사용했을 때와 +?를 사용했을 때의 결과를 비교하면 이해가 쉽습니다.

 

첫 번째 예제는 가장 크게 일치하는 cat~mat의 문자열을 패턴으로 인식합니다.

두 번째 예제는 가장 적게 일치하는 cat를 문자열의 패턴으로 인식하였습니다.

 

public void Example() {
    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.

'JAVA 개인공부' 카테고리의 다른 글

[JAVA] 정규표현식(regex) [1/2]  (0) 2021.06.18