[Java] 정규표현식

자바의 정규표현식 처리

자바에서 정규표현식을 사용하는 방법에는 여러 가지가 있다.


1. String 클래스 사용

String 클래스에 정의된 메소드 중 정규표현식(regex 문자열 표현)을 처리할 수 있는 메소드는 다음과 같다. 메소드 중 일부는 일반적으로 문자열 처리를 위해 사용했던 메소드들임을 알 수 있다.

boolean matches(String regex)

해당 문자열이 주어진 정규표현식과 일치하는 지에 대한 참/거짓 값을 반환한다.


String replaceAll(String regex, String replacement)

해당 문자열에서 주어진 정규표현식과 일치하는 부분 문자열을 주어진 문자열로 대체한다.


String replaceFirst(String regex, String replacement)

해당 문자열에서 주어진 정규표현식과 일치하는 부분 문자열 중 첫 번째 문자열을 주어진 문자열로 대체한다.


String[] split(String regex)

주어진 정규표현식과 일치하는 문자열을 기준으로 해당 문자열을 분리한다.


String[] split(String regex, int limit)

위 메소드와 동일한 기능을 수행한다. 두 번째 파라미터는 문자열 분리 결과로 반환되는 문자열 배열의 길이를 제한하는 역할을 한다.


이와 같이 String 클래스에 정의된 여러 메소드의 인자로 정규표현식을 전달함으로써 특정 문자열에 대해 문자열 교체, 분리와 같은 처리를 수행할 수 있다.


2. Pattern, Matcher

java.util.regex 패키지에 존재하는 PatternMatcher 클래스를 이용하면 정규표현식으로 다양한 처리를 할 수 있다. 이 방법은 정규표현식을 사용한 패턴 매칭을 위해 자바에서 제공하는 클래스를 사용하는 것이다. 문서regex를 통해 각 클래스에서 제공하는 메소드 및 처리 방식을 확인할 수 있다. 두 클래스 모두 생성자를 통한 객체 생성은 불가능하며 해당 객체를 반환하는 메소드 호출을 통해 객체를 생성한다.

사용 순서는 크게 세 단계로 정리할 수 있다.

  1. 정규표현식을 나타내는 문자열이 Pattern 클래스의 인스턴스로 컴파일된다. Pattern 클래스의 compile() 메소드를 이용하여 주어진 정규표현식을 패턴으로 컴파일한다.
  2. 컴파일된 Pattern 객체는 메소드를 통해 주어진 문자 시퀀스를 정규식과 일치시키는 Matcher 객체를 생성한다. Pattern 클래스의 matcher() 메소드를 이용하여 주어진 입력(문자열)과 정규표현식을 매칭시키는 Matcher를 생성한다.
  3. Matcher 인스턴스의 메소드를 사용하여 다양한 매칭 작업을 수행한다.
    Pattern pattern = Pattern.compile("정규표현식");  
    Matcher matcher = pattern.matcher("대상문자열");
    


Pattern 클래스는 정규표현식의 컴파일된 표현이며, Matcher 클래스는 패턴을 해석하여 문자 시퀀스에서 어떤 것이 일치하는지 판별하는 작업을 수행하는 엔진이다. 쉽게 말해 Pattern 객체는 정규표현식 패턴이고, Matcher 객체는 패턴인 Pattern을 해석하여 주어진 문자열에 대해 패턴 매칭 기능을 수행하는 엔진 역할을 수행한다.

Matcher의 매턴 매칭 관련 메소드는 다음과 같다.

  1. matches() 메소드: 입력 시퀀스 전체를 패턴과 일치시키는 작업을 수행한다. 즉, 정규표현식이 대상 문자열 전체와 일치하는지 아닌지 판별한다. 정규표현식이 대상 문자열 일부에만 매칭된다면 거짓을 반환한다.
  2. lookingAt() 메소드: 입력 시퀀스의 처음부터 패턴과 일치시키는 작업을 수행한다. 대상 문자열의 첫 번째 부터 매칭 작업을 하는 것은 matches() 메소드와 동일하지만 대상 문자열 전체를 대상으로 하지는 않는다.
  3. find() 메소드: 입력 시퀀스 중 패턴과 일치하는 하위 시퀀스를 찾는 작업을 수행한다. 대상 문자열의 시작 부터 매칭 작업을 수행하며 이전 호출에서 매칭되는 경우를 찾은 경우, 다음 매칭은 일치하지 않았던 시퀀스부터 시작한다. 주로 반복문과 함께 사용하여 매칭 작업을 수행한다.


코드 예제

String 클래스와 PatternMatcher 클래스를 사용하여 정규표현식을 통한 문자열 패턴 매칭을 수행하는 코드는 다음과 같다.


1. String 클래스의 matches() 메소드

비교문자열.matches("정규표현식")  


matches() 메소드를 사용하면 해당 문자열이 정규표현식과 일치하는지 알 수 있다. 비교하려는 문자열 객체의 matches() 메소드를 호출할 때 인자로 정규표현식 문자열을 전달하면 된다. 메소드의 반환값은 참 또는 거짓이다. 문자열의 패턴 매칭 결과를 참 또는 거짓으로 처리하는 로직에서 사용될 수 있다.

String regexEx1 = "github.com";
String regexEx2 = "https://github.com/github";

boolean result1 = regexEx1.matches("^github.com$");
System.out.println(result1);

boolean result2 = regexEx2.matches("(github.com)");
System.out.println(result2);
true
true


2. String 클래스의 replaceAll() 메소드

비교문자열.replaceAll("정규표현식", "대체문자열")  


replaceAll() 메소드를 사용하면 패턴 매칭을 통해 해당 문자열 중 일부를 원하는 문자열로 변환할 수 있다. 비교하려는 문자열 객체의 replaceAll() 메소드를 호출할 때 인자로 정규표현식 문자열과 대체하고자 하는 문자열을 전달하면 된다. 메소드의 반환값은 대체된 결과 문자열 객체이다. 문자열 중 특정 문자열을 원하는 문자열로 교체하는 로직(패턴 매칭 후 문자열 교체)에서 사용될 수 있다.

String regexEx = "깃허브 010-1234-5678 github@github.co.kr";
String result = regexEx.replaceAll("([a-z]{6})", "git");
System.out.println(result);
깃허브 010-1234-5678 git@git.co.kr


3. String 클래스의 split() 메소드

대상문자열.split("정규표현식")  


split() 메소드를 사용하면 패턴 매칭을 통해 해당 문자열을 특정 문자열을 기준으로 분리시킬 수 있다. 분리 대상이 되는 문자열 객체의 split() 메소드를 호출할 때 인자로 정규표현식 문자열을 전달하면 된다. 메소드의 반환값은 분리된 문자열을 원소로 갖는 배열 객체이다. 문자열을 특정 문자열을 기준으로 분리하는 로직에서 사용될 수 있다.

String regexEx = "https://github.co.kr/github";
String[] result = regexEx.split("([\\W]+)");
for(String item:result) System.out.println(item);
https  
github  
co  
kr  
github 


4. Pattern과 Matcher 클래스 사용

Pattern pattern = Pattern.compile("[a-z]+"); 

Matcher matcher1 = pattern.matcher("awefs");
Matcher matcher2 = pattern.matcher("23342");
Matcher matcher3 = pattern.matcher("sdfasa23423sdfa50023");

System.out.println("matches(): " + matcher1.matches() + ", " + matcher2.matches() + ", " + matcher3.matches());
System.out.println("lookingAt(): " + matcher1.lookingAt() + ", " + matcher2.lookingAt() + ", " + matcher3.lookingAt() + "\n");
matcher3.reset();

System.out.println(
  "matcher3.find(): " + matcher3.find() + "\n"
  + "matcher3.toMatchResult(): " + matcher3.toMatchResult() + "\n"
  + "matcher3.find(): " + matcher3.find() + "\n"
  + "matcher3.toMatchResult(): " + matcher3.toMatchResult() + "\n");
matcher3.reset();

while(matcher3.find()) {
  System.out.println("matcher3.group(): " + matcher3.group() + "\n"
    + "matcher3.start(): " + matcher3.start() + "\n"
    + "matcher3.end(): " + matcher3.end() + "\n");
}
matches(): true, false, false  
lookingAt(): true, false, true

matcher3.find(): true  
matcher3.toMatchResult(): java.util.regex.Matcher[pattern=[a-z]+ region=0,20 lastmatch=sdfasa]  
matcher3.find(): true  
matcher3.toMatchResult(): java.util.regex.Matcher[pattern=[a-z]+ region=0,20 lastmatch=sdfa]

matcher3.group(): sdfasa  
matcher3.start(): 0  
matcher3.end(): 6  
matcher3.group(): sdfa  
matcher3.start(): 11  
matcher3.end(): 15  


참고

  • <https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html
    https://docs.oracle.com/javase/8/docs/api/java/util/regex/Matcher.html>

Categories:

Updated:

Comments