back end/java

[java] 문자열 자르기 함수 split 함수 사용 시 주의 사항. 문자열 자르는 방법

노루아부지 2024. 1. 17. 22:58

결론부터 말하면, 저는 split 함수를 추천하지 않습니다.

그 이유는 split 함수는 문자열을 자를 때 '문자'가 아닌 '정규식'으로 자르기 때문입니다.

이것은 replace 함수도 마찬가지입니다.

 

 

split 함수

 

intellij에서 split 함수의 설명을 보면 아래와 같습니다.

문자열 자르기 함수 split 함수 사용 시 주의사항. 문자열 자르는 방법

 

split 함수의 설명에서 제일 중요한 것은 파란색으로 되어 있는 "regular expression" 즉 정규식입니다.

그렇기 때문에 split 함수는 정말 신중하게 사용해야 합니다.

 

 

split - 정규식의 위험성

 

먼저 아래의 예제를 봅시다.

 

예제 1. 정상동작

public static void main(String[] args) {
  String str = "010-1111-2222";
  String[] split = str.split("-");

  for (String s : split) {
    System.out.println(s);
  }
}

 

이 예제의 실행 결과는 다음과 같이 예상한 것처럼 화면에 출력됩니다.

문자열 자르기 함수 split 함수 사용 시 주의사항. 문자열 자르는 방법

 

 

하지만 다음 예제는 정상동작하지 않습니다.

 

예제 2. 비정상 동작

public static void main(String[] args) {
  String str = "010|1111|2222";
  String[] split = str.split("|");

  for (String s : split) {
    System.out.println(s);
  }
}

 

이 코드의 결과는 어떻게 될까요?

기대하는 결과는 예제 1과 같겠지만 실제로는 아래와 같습니다.

문자열 자르기 함수 split 함수 사용 시 주의사항. 문자열 자르는 방법

 

예제 2를 정상동작하게 하려면 아래와 같이 \\(백슬래시 두 번)을 넣어야 합니다.

public static void main(String[] args) {
  String str = "010|1111|2222";
  String[] split = str.split("\\|");

  for (String s : split) {
    System.out.println(s);
  }
}

 

 

예제 3. 비정상 동작

그렇다면 파이프라인(|) 말고 다른 구분자는 어떻게 동작할까요?

dot(.)은 아무 문제없을 것처럼 생각할 수 있는데요

public static void main(String[] args) {
  String str = "12345.678";
  String[] split = str.split(".");

  for (String s : split) {
    System.out.println(s);
  }
}

 

dot(.)을 기준으로 12345와 678로 나누고 싶은데 결과는 다음과 같이 아무것도 없습니다.

문자열 자르기 함수 split 함수 사용 시 주의사항. 문자열 자르는 방법

 

정규식에서 dot(.)은 무작위의 한 글자를 의미하기 때문에 모든 문자가 토큰이 되어 남는 게 없게 되는 것입니다.

 

 

 

정규표현식

split 사용 시 뭔가 이상하게 동작하는 것 같으면 정규식을 의심하면 됩니다. 이상동작이 발생할 경우 해결방법이 없는 것은 아니지만 문제가 발생한 다음은 이미 늦었습니다. 컴파일 오류가 발생하지 않기 때문이죠.

그렇다고 정규표현식을 공부하지 않고 몇몇 문자만 외우기에는 정규표현식에서 사용하는 문자가 너무 많습니다.

 

  1. 확장문자 (: backslash)
    • s : 공백 문자(스페이스, 탭, 폼 피드, 라인피드)
    • b : 단어의 경계
    • B 이를 제외한 모든 문자 매칭
    • d : 숫자
    • D : 숫자가 아닌 문자 [^0-9]와 동일
    • w : 알파벳, 숫자로 된 문자, 밑줄 기호(_) [A-Za-z0-9]
    • W : w의 반대 문자 [^a-za-z0-9]
    • 특수문자 : 특수문자 자체를 의미 예) + (+ 기호 자체)
  2. 특수문자
    • * : 0회 이상 반복
    • + : 1회 이상 반복
    • ? : 0 또는 1개의 문자 매칭
    • . : 정확히 1개 문자 매칭
  3. 플래그
  4. 기타
    • () : 괄호로 묶인 패턴은 매칭된 다음, 그 부분을 기억한다.
    • $1,...,$9 : 괄호로 캡처한 부분 문자열이 저장됨.
    • | : ~또는~
    • {} : 반복 횟수

 

 

문자열을 자르는 방법 - StringTokenizer

문자열을 자르기 위한 추천 함수는 바로 StringTokenizer입니다.

StringTokenizer는 아래 이미지와 같이 정규식이 아닌 문자를 사용하여 자르기 때문에 이상동작을 할 가능성이 없습니다.

문자열을 자르는 방법 - StringTokenizer

 

 public static void main(String[] args) {
  String str = "010|1111|2222";

  StringTokenizer st = new StringTokenizer(str, "|");
  while (st.hasMoreTokens()) {
    System.out.println(st.nextToken());
  }
}

 

위 코드의 실행 결과는 아래와 같이 정상적으로 동작합니다.

문자열을 자르는 방법 - StringTokenizer

 

728x90
loading