Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

Java 정규식(Regex)으로 문자열 내 모든 특수 문자를 끝으로 이동하는 방법

문자열을 다루다 보면 특수 문자를 일반 문자와 분리해야 하는 경우가 종종 있습니다. 이번 글에서는 Java 정규식(Regular Expression)을 활용해 문자열에 포함된 모든 특수 문자를 찾아내고, 이를 문자열의 맨 뒤로 이동시키는 방법을 두 가지 예제를 통해 살펴보겠습니다.

특수 문자를 매칭하는 정규식

다음 정규식은 영문 알파벳(a-z, A-Z), 숫자(0-9), 공백을 제외한 모든 특수 문자와 일치합니다.

"[^a-zA-Z0-9\\s+]"

대괄호 안의 ^는 부정(negation)을 의미하므로, 위 패턴은 영문자·숫자·공백이 아닌 문자, 즉 특수 문자만 골라내는 역할을 합니다.

처리 방식

모든 특수 문자를 문자열 끝으로 옮기려면 다음 순서로 처리합니다.

1. 위 정규식으로 입력 문자열에서 특수 문자를 모두 찾습니다.
2. 찾은 특수 문자들을 하나의 빈 문자열에 차곡차곡 연결합니다.
3. 나머지 일반 문자들은 별도의 문자열에 연결합니다.
4. 마지막으로 두 문자열을 합치면 특수 문자가 뒤로 이동한 결과가 완성됩니다.

예제 1: charAt()과 matches() 활용

첫 번째 방법은 문자열을 한 글자씩 순회하면서 각 문자가 정규식과 일치하는지 검사하는 방식입니다.

public class RemovingSpecialCharacters {
    public static void main(String args[]) {
        String input = "sample # text * with & special@ characters";
        String regex = "[^a-zA-Z0-9\\s+]";
        String specialChars = "";
        String inputData = "";
        for(int i=0; i< input.length(); i++) {
            char ch = input.charAt(i);
            if(String.valueOf(ch).matches(regex)) {
                specialChars = specialChars + ch;
            } else {
                inputData = inputData + ch;
            }
        }
        System.out.println("Result: "+inputData+specialChars);
    }
}

실행 결과

Result: sample text with special characters#*&@

출력 결과를 보면 원래 문자열 중간에 있던 #, *, &, @가 모두 문자열 끝으로 이동한 것을 확인할 수 있습니다.

예제 2: Pattern과 Matcher 클래스 활용

두 번째 방법은 java.util.regex 패키지의 Pattern 클래스와 Matcher 클래스를 사용하는 보다 정석적인 방식입니다. 컴파일된 패턴으로 문자열을 검사하면서 특수 문자를 수집하고, appendReplacement() 메서드로 해당 문자를 제거한 후 마지막에 합칩니다.

import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
    public static void main(String args[]) {
        String input = "sample # text * with & special@ characters";
        String regex = "[^a-zA-Z0-9\\s+]";
        String specialChars = "";
        System.out.println("Input string: \n"+input);
        // 패턴 객체 생성
        Pattern pattern = Pattern.compile(regex);
        // 문자열에서 컴파일된 패턴과 일치하는 부분 검색
        Matcher matcher = pattern.matcher(input);
        // 빈 StringBuffer 생성
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            specialChars = specialChars+matcher.group();
            matcher.appendReplacement(sb, "");
        }
        matcher.appendTail(sb);
        System.out.println("Result: \n"+ sb.toString()+specialChars );
    }
}

실행 결과

Input string:
sample # text * with & special@ characters
Result:
sample text with special characters#*&@

마무리

두 예제 모두 동일한 결과를 출력하지만, 실무에서는 문자열 반복 처리 시 String 대신 StringBuilderStringBuffer를 사용하는 것이 성능 면에서 유리합니다. 또한 정규식 패턴에 한글 등 유니코드 문자를 포함하고 싶다면 [^a-zA-Z0-9\\s+] 대신 [^\\w\\s]나 유니코드 범위를 활용하는 방법도 고려해 볼 수 있습니다. 상황에 맞는 정규식을 설계해 효율적으로 문자열을 가공해 보세요.