자바에서 문자열을 나눌 때 사용할 수 있는 도구는 split과 StringTokenizer가 있다.
둘의 동작을 살펴보면서 사용할 때 유의점을 정리해보려고 한다. 동시에 둘의 차이점에 대해서도 알아보겠다!
String.Split()
String str = "123,45,234,456";
String[] splitArray = str.split(",");
for (String s: splitArray) {
System.out.println(s);
}
split은 특정문자를 기준으로 문자열을 나눠 String[] 배열을 반환합니다. 저는 이런식으로 구분자를 넣어서 사용해왔습니다.
메서드를 타고 들어가서 자세한 설명을 읽어봅시다
주어진 정규식(regex)과 일치하는 문자열을 기준으로 이 문자열을 분할합니다.
이 메서드는 주어진 표현식과 0의 제한 인수를 사용하여 두 인수 split 메서드를 호출하는 것처럼 작동합니다. 따라서 후행 빈 문자열은 결과 배열에 포함되지 않습니다.
예를 들어 문자열 "boo:and:foo"는 다음 표현식을 사용하여 다음과 같은 결과를 생성합니다.
정규 표현식과 결과를 보여주는 분할 예
정규 표현식 결과
: { "boo", "and", "foo" }
o { "b", " ", ":and:f" }
매개변수: regex – 구분 정규 표현식
반환: 주어진 정규 표현식과 일치하는 부분에 대해 이 문자열을 분할하여 계산된 문자열 배열
예외: PatternSyntaxException – 정규 표현식의 구문이 유효하지 않은 경우
적용 버전: 1.4
See Also: java.io.Serializable.Pattern
사양 JSR-51
- 구분자로 사용되는 regex 인수는 정규식형태로 넣을 수 있다
- 후행 빈 문자열이 결과 배열에 포함되지 않는다
후행 빈 문자열이 결과 배열에 포함되지 않으므로, 다음과 같은 경우에 마지막 빈 문자열은 포함되지 않는다.
String str = "123,45,234,456,";
String[] splitArray = str.split(",");
for (String s: splitArray) {
System.out.println("["+s+"]");
}
String str = "123,45,234,456,,,,,,,,,";
String[] splitArray = str.split(",");
for (String s: splitArray) {
System.out.println("["+s+"]");
}
하지만 앞의 빈 문자열은 포함이 된다
String str = ",123,45,234,456";
String[] splitArray = str.split(",");
for (String s: splitArray) {
System.out.println("["+s+"]");
}
String str = ",,,,,123,45,234,456";
String[] splitArray = str.split(",");
for (String s: splitArray) {
System.out.println("["+s+"]");
}
중간의 빈 문자열도 포함됨
String str = "123,45,,,,,234,456";
String[] splitArray = str.split(",");
for (String s: splitArray) {
System.out.println("["+s+"]");
}
결론: split()을 쓸 때는 정규표현식 형태로 구분자를 넣을 수 있으며, 마지막에 붙는 빈 문자열은 포함되지 않는다.
StringTokenizer
String str = "123,45,234,456";
StringTokenizer st = new StringTokenizer(str, ",");
while (st.hasMoreTokens()) {
System.out.println("[" + st.nextToken() + "]");
}
StringTokenizer 객체를 만들 때 구분자를 넣어주고, st.nextToken() 방식으로 구분된 문자열을 차례로 받아온다.
타고 들어가서 생성자의 설명을 읽어보자
지정된 문자열에 대한 문자열 토크나이저를 구성합니다. delim 인수의 문자는 토큰을 구분하기 위한 구분 기호입니다. 구분 기호 문자 자체는 토큰으로 처리되지 않습니다.
delim이 null인 경우 이 생성자는 예외를 발생시키지 않습니다. 그러나 결과 StringTokenizer에서 다른 메서드를 호출하려고 하면 NullPointerException이 발생할 수 있습니다.
Params: str – 구문 분석할 문자열
delim - 구분 기호
오류: NullPointerException – str이 null인 경우
Split과 달리 String문자열을 넣어 해당 문자를 기준으로 문자열을 분리한다
split과 마찬가지로 구분자는 토큰으로 처리되지 않는다고 한다
전체 설명을 읽어보면 다음과 같이 말한다
문자열 토크나이저 클래스를 사용하면 애플리케이션이 문자열을 토큰으로 나눌 수 있습니다. 토큰화 방법은 StreamTokenizer 클래스에서 사용하는 방법보다 훨씬 간단합니다. StringTokenizer 메서드는 식별자, 숫자 및 인용된 문자열을 구별하지 않으며 주석을 인식하고 건너뛰지도 않습니다.
구분 기호 집합(토큰을 구분하는 문자)은 생성 시 또는 토큰별로 지정할 수 있습니다.
StringTokenizer의 인스턴스는 값이 true 또는 false인 returnDelims 플래그를 사용하여 생성되었는지 여부에 따라 두 가지 방식 중 하나로 작동합니다.
- 플래그가 false인 경우 구분 기호 문자는 토큰을 구분하는 역할을 합니다. 토큰은 구분 기호가 아닌 최대 연속 문자 시퀀스입니다.
- 플래그가 true이면 구분 기호 문자 자체가 토큰으로 간주됩니다. 따라서 토큰은 하나의 구분 기호 문자이거나 구분 기호가 아닌 최대 연속 문자 시퀀스입니다.
StringTokenizer 개체는 토큰화할 문자열 내에서 현재 위치를 내부적으로 유지합니다. 일부 작업에서는 처리된 문자를 지나서 이 현재 위치를 앞당깁니다. StringTokenizer 개체를 생성하는 데 사용된 문자열의 하위 문자열을 가져와 토큰을 반환합니다.
다음은 토크나이저 사용의 한 예입니다.
StringTokenizer st = new StringTokenizer("this is a test");
while (st.hasMoreTokens()) {
System.out.println(st.nextToken());
}
는 다음 출력을 인쇄합니다.
this
is
a
test
StringTokenizer는 새 코드에서는 사용이 권장되지 않지만 호환성 이유로 유지되는 레거시 클래스입니다. 이 기능을 원하는 사람은 대신 String의 분할 방법이나 java.util.regex 패키지를 사용하는 것이 좋습니다. 다음 예에서는 String.split 메소드를 사용하여 문자열을 기본 토큰으로 분할하는 방법을 보여줍니다.
String[] result = "this is a test".split("\\s");
for (int x=0; x<result.length; x++)
System.out.println(result[x]);
는 다음 출력을 인쇄합니다:
this
is
a
test
도입 버전: 1.0
참조: java.io.StreamTokenizer
작성자: unascribed
StringTokenizer는 flag를 사용하여 구분자도 포함하여 토큰을 만들 수 있다고 한다
몰랐던 사실인데, StringTokenizer는 새 코드에서 사용이 권장되지 않는다고 한다!!! 대신 split을 사용하라고 split 사용법을 알려준다..
split처럼 마지막 토큰이 포함되는지 여부를 알려주지 않으니 직접 테스트해보겠다.
String str = "123,45,234,456,";
StringTokenizer st = new StringTokenizer(str, ",");
while (st.hasMoreTokens()) {
System.out.println("[" + st.nextToken() + "]");
}
String str = "123,45,234,456,,,,,,,,,,";
StringTokenizer st = new StringTokenizer(str, ",");
while (st.hasMoreTokens()) {
System.out.println("[" + st.nextToken() + "]");
}
마지막 공백문자열을 가볍게 무시해버린다
String str = ",,,,,,,,123,45,,,,,,,,234,456,,,,,,,,";
StringTokenizer st = new StringTokenizer(str, ",");
while (st.hasMoreTokens()) {
System.out.println("[" + st.nextToken() + "]");
}
앞이든 중간이든 뒤든 공백문자열은 싹 무시하는 걸 볼 수 있다.
이렇게 다 무시하는 게 좋을 수도 있지만, 안좋을 수도 있을 것 같다
결론:
- Split()은 마지막 공백문자열을 무시한다
- StringTokenizer는 모든 공백문자열을 무시한다
- StringTokenizer를 아무 생각없이 사용했었는데, split이 자바에서 권장되는 도구이다
- 다음에는 split을 사용해야겠다! (뒷쪽 공백이 포함되지 않는다는 것도 잘 기억해둬야겠다)
'프로그래밍 언어 > Java' 카테고리의 다른 글
[JAVA] public private 메소드 정렬 순서 결정하는법 (0) | 2023.10.28 |
---|---|
[JAVA] StringBuilder 비우기(초기화하기) (1) | 2023.10.28 |
[Java] 자바 코드 컨벤션 정리(Google Java Style Guide) (0) | 2023.10.18 |
[JAVA] StringBuffer와 StringBuilder의 차이점 (0) | 2023.10.11 |
[JAVA] Disjoint Set과 Union-Find 알고리즘(백준 1717 집합의 표현) (3) | 2023.10.10 |