오늘은 자바에서 split을 사용하면서 정규식 문자를 구분자로 자를 때 종종 발생하는 이슈에 대해서 정리해 보려고 한다.
그 중에서 점(.)을 기준으로 split 했을 때의 내용을 알아보려고 한다.
보통 자바에서는 split을 사용할 때 정규 표현식 처리를 할 때 주의해서 사용해야 한다. 그렇지 않으면 에러가 발생하거나 원하지 않은 결괏값이 나와 시스템의 장애가 될 수 있다.
split(".")
정규 표현식 "."을 기준으로 특정 문자열을 split 하고자할 때 이를 제대로 이해하지 않은 상태에서 사용하게 되면 예상치 못한 결괏값이 나와 문제가 될 수 있다. 간단하게 개념과 특징을 살펴보도록 하자.
정규 표현식 메타 문자
split(".")에서의 점(.)은 정규 표현식의 메타 문자 중 하나로, 어떤 문자와도 일치하는 와일드카드다. 이는 문자열을 임의의 위치에서 분할하도록 유발할 수 있다. 예를 들어, "apple.banana.orange"와 같은 문자열을 split(".")으로 분할하면 예상과 다른 결괏값이 나오게 된다.
이스케이프 처리
점(.)이 문자 그대로 해석되도록 하려면 이스케이프 처리가 필요하다. split("\.")와 같이 백슬래시를 사용하여 점(.)을 이스케이프하면 된다. 자바에서는 이스케이프 처리를 위해 백슬래시를 두 번 사용하는데, 이는 정규 표현식의 이스케이프 문자로 백슬래시를 사용하기 때문이다.
문자열 분할
split("\.")을 사용하면 문자열을 점(.)을 기준으로 올바르게 분할할 수 있다. 예를 들어, "apple.banana.orange"를 split("\.")으로 분할하면 "apple", "orange", "banana"와 같은 문자열 배열로 반환하게 된다.
split(".") 예제 소스 코드
package com.demo.system;
import java.util.Arrays;
import java.util.stream.Collectors;
public class TestMain {
public static void main(String[] args) {
splitTest("abcsefg", ".");
}
/**
* split을 이용한 정규식 문자 테스트 method
*/
public static void splitTest (String originData, String regex) {
System.out.println("---------------------------------------------");
System.out.println("* 원본 데이터 : " + originData);
System.out.println("* 정규식 문자 : " + regex);
System.out.println("---------------------------------------------");
String regexData = Arrays.stream(originData.split("")).collect(Collectors.joining(regex));
System.out.println("* 원본 + 정규식 데이터 : " + regexData);
System.out.println("---------------------------------------------");
String [] arr = regexData.split(regex);
int arrLength = arr.length;
System.out.println("* split size : " + arrLength);
System.out.println("---------------------------------------------");
for (int i = 0; i < arrLength; i++) {
System.out.println(arr[i]);
}
}
}
split을 이용하여 테스트할 수 있도록 메서드를 만들어 줬다.
- 인자값 1 : split 대상 문자열
- 인자값 2 : split 구분값 (위의 메서드에서는 인자값1과 join 처리를 하고 나서 split 처리를 하기 위한 용도)
테스트로는 인자값1에 "abcdefg", 인자값 2에 "." 값을 넣고 메서드를 호출하였다.
- "a.b.c.d.e.f.g"
결과는 어떻게 나오는지 실행 결과를 확인해 보자.
실행 결과

실행 결과는 역시 다른 결과가 나왔다. 기대했던 결과는 "a", "b", "c", "D"... 각각 split 되어 배열에 담기면 size가 7이 나왔어야 했는데, split이 되지 않아 배열 size는 0이 나왔다.
"."는 정규식 문자로 split에서 일반 문자와는 다르게 사용이 되기 때문에 발생한 이유다. split에서는 "."를 \n(개행문자)를 제외한 모든 문자를 의미해 모든 문자를 전부 split 처리가 되어 split 된 값이 없이 반환이 된다.
이에 대한 해결 방안으로는 "."를 정규식 문자가 아닌 일반 문자로 인식할 수 있도록 값을 변경해 주면 된다.
split("\\.") 예제 소스 코드
소스 코드상에서 split을 처리하는 코드 부분에 "\\"를 추가해 줬다.
String [] arr = regexData.split("\\" + regex);
"\\"를 추가하게 되면 정규식 문자를 일반 문자로 인식할 수 있기 때문이다.
실행 결과

"."를 일반 문자로 인식할 수 있도록 처리했더니 원하는 결괏값이 나온 것을 확인할 수 있다.
split(".") 사용 시 주의사항
오늘 정리한 바와 같이 split(".")을 하는 경우 원하는 값이 나오지 않는다는 것을 확인할 수 있었고, 해결 방법을 통해서 정규 표현식 "."는 이스케이프 처리를 통해서 split이 가능하다는 것까지 알아볼 수 있었다. 그래서 "."를 기준으로 split이 필요한 경우에는 사용하기 전에 주의사항을 먼저 점검해 보는 것이 좋을 것 같아서 정리해 보았다.
정규 표현식 사용
split(".")는 정규 표현식을 기반으로 동작한다. 그렇기 때문에 점(.)은 정규 표현식에서 메타 문자로 해석되므로 문자 그대로 점을 찾고 싶을 때는 백슬래시로 이스케이프 처리를 해야 한다.
빈 문자열 처리
split(".")는 점(.)을 구분자로 사용하여 문자열을 분할하는데, 연속된 점(.)이 있는 경우에는 빈 문자열이 생성될 수 있다. "apple..banana"와 같은 문자열을 split("\\.")로 분할하면 "apple", "", "banana"와 같이 빈 문자열이 포함될 수 있다.
정확한 구분자 지정
구분자로 사용되는 문자열이 문자열 내에 여러 번 나타나는 경우 split(".")을 사용할 때 주의해야 한다. 이때, 정확한 구분자를 지정하여 원하는 방식으로 문자열을 분할할 수 있도록 해야 한다.
성능
split(".")는 문자열의 길이에 따라 성능이 저하될 수 있다. 큰 문자열이나 빈번한 호출에서는 성능 문제가 발생할 수 있다.
이러한 주의사항을 숙지하고 적절히 활용하는 것이 중요하다.
마무리
이슈 원인
split에서는 "."를 \n(개행문자)를 제외한 모든 문자를 의미해 모든 문자를 전부 split 처리가 되어 split 된 값 없이 반환
해결 방안
split("\\.");
오늘은 이렇게 자바의 정규 표현식 "."을 기준으로 split 하는 방법을 정리해 보았고, 이스케이프 처리와 주의사항까지 간단하게 정리해 봤다. 정규 표현식을 숙지하고 학습하는 것은 항상 중요하고, 정규 표현식을 기준으로 split을 한다는 것은 에러까지 발생할 수 있으므로 반드시 알아두는 것이 좋다.
'Java > Java' 카테고리의 다른 글
| [java] 자바 split 정규식 문자 사용하기 (0) | 2023.01.22 |
|---|---|
| [java] 자바 split 파이프라인 "|" 검색하기 (0) | 2023.01.20 |
| [java] 자바 문법 에러 'Dangling meta character '' near index 0' 해결하기 (split 에러 이슈) (0) | 2023.01.18 |
| [java] 자바 문법 에러 Unmatched closing ')' 해결하기 (split 에러 처리) (1) | 2023.01.16 |
| [java] 자바 문법 에러 Illegal repetition 해결하기 (split 에러) (0) | 2023.01.15 |