public String[] split(String regex);
-> 문자열을 regex(정규식)에 맞춰서 분리한다.
public String[] split(String regex, int limit);
-> limit 만큼 문자열을 자름
split (String regex)는 문자열을 정규식에 맞춰서 분리합니다.
split (String regex, int limit)는 똑같이 문자열을 정규식에 맞춰서 분리하는데 limit만큼 문자열을 자르는거예요.
만약 두 번째 인자로 2가 들어갔다면, 잘린 문자열의 개수가 2개가 될때까지만 자르는거죠.
기본 split메서드를 사용하여 문자열을 @ 구분자를 이용해 분리해봅시다.
public class Main {
public static void main(String[] args) {
String str = "jhnyang@tistory@com";
String[] strAry = str.split("@");
for (String s : strAry)
System.out.println(s);
}
}
str문자열에 총 @가 두개 들어가있으니 strAry는 세개로 분리되었을 거예요. 반복문으로 하나하나씩 출력해서 잘 파싱됐는지 확인해봅시다.
public class Main {
public static void main(String[] args) {
String str = "jhnyang.tistory.com";
String[] strAry = str.split("."); //-->잘못된 사용예
for (String s : strAry)
System.out.println(s);
}
}
실제로 위와 같이 작성하고 출력해보면 결과가 아무것도 없는 것을 확인할 수 있습니다.
split는 정규표현식으로 문자를 분리하는데요. 정규표현식에서 점(.)은 하나의 문자와 대응하는 일종의 메타문자이기 때문입니다.
public class Main {
public static void main(String[] args) {
String str = "jhnyang.tistory.com";
String[] strAry = str.split("\\.");
for (String s : strAry)
System.out.println(s);
}
}
메타문자가 아닌 문자 그대로 특수문자를 구분자로 사용하고 싶을 경우에는 이스케이프 문자인 "\"를 앞에 붙여줘야 해요. 그래야 위처럼 결과가 제대로 파싱됩니다.
split의 경우 정규식으로 문자열을 분리하였을 때, 빈 문자열이 결과로 있다면 이를 하나의 문자열로 취급합니다.
public class Main {
public static void main(String[] args) {
String ipv6 = "fe80::bda7:2e2:a235:8f98";
String[] octets = ipv6.split(":");
for (int cnt =1; cnt<= octets.length; cnt++ )
System.out.println(cnt + "번째옥탯:" + octets[cnt-1]);
}
}
배열로 통째로 리턴받아서 for문을 이용해 다 꺼낼 필요 없이, 특정 위치 부분을 바로 문자열에 저장해 접근하고 싶을 수 있어요.
전화번호에서 지역번호 부분만 파싱해, 문자열에 저장하는 예제를 통해 사용법을 익혀봅시다.
public class Main {
public static void main(String[] args) {
String tel = "02-123-4567";
String area_nbr = tel.split("-")[0];
System.out.println(area_nbr);
}
}
split는 정규식을 받기 때문에 당연히 구분자를 여러개 둘 수 있습니다.
public class Main {
public static void main(String[] args) {
String mail = "hello-kitty@hellokitty.com";
String[] strAry = mail.split("-|@|\\.");
for (String s : strAry)
System.out.println(s);
}
}
이번에는 간단히 limit를 사용해봄으로써 결과를 비교해봅시다.
public class Main {
public static void main(String[] args) {
String str = "123::4:67:10::::";
String[] noLimit = str.split(":");
String[] limitTwo = str.split(":", 2);
String[] limitPlus = str.split(":", 7);
String[] limitZero = str.split(":", 0);
String[] limitMinus = str.split(":", -1);
System.out.println("-----noLimit-----");
for (int cnt =0; cnt< noLimit.length; cnt++ )
System.out.println(cnt + "위치:" + noLimit[cnt]);
System.out.println("-----limitTwo-----");
for (int cnt =0; cnt< limitTwo.length; cnt++ )
System.out.println(cnt + "위치:" + limitTwo[cnt]);
System.out.println("-----limitPlus-----");
for (int cnt =0; cnt< limitPlus.length; cnt++ )
System.out.println(cnt + "위치:" + limitPlus[cnt]);
System.out.println("-----limitZero-----");
for (int cnt =0; cnt< limitZero.length; cnt++ )
System.out.println(cnt + "위치:" + limitZero[cnt]);
System.out.println("-----limitMinus-----");
for (int cnt =0; cnt< limitMinus.length; cnt++ )
System.out.println(cnt + "위치:" + limitMinus[cnt]);
}
}
빨간색 박스부분! - split(String regex)와, split (String regex, 0)일 경우!
맨 처음 리미트 없이 하나의 인자만 넣어줬을 때와 limit 값이 0일 때의 결과가 동일한 것을 확인할 수 있습니다.
즉 두번째 매개변수 limit의 디폴트 값은 0입니다.
limit값이 0일 경우에는 문자열이 구분자로 구분이 되었어도 맨 뒤의 값들이 다 빈 문자열이면 이를 무시합니다.
보면 결과 인덱스가 4까지만 있죠?! 배열 중간 중간 빈 문자열이 껴있는 것은 토큰으로 인식하지만 마지막이 빈문자열인 것들은 무시해요.
limit에다가 인자로 2를 넣어줬더니 문자열을 두개로 분리하고 더 이상 구분자를 기준으로 나누지 않은 것을 확인할 수 있습니다. 뒤에 결과가 없어도 분리가 된 이상 limit개수만큼 리턴해줬어요.
limitPlus부분에서 확인할 수 있듯이
리미트가 양수일 경우에는 뒤에 구분결과가 빈문자열이여도 그 리미트 개수만큼 다 쳐서 리턴해줍니다.
limt로 7을 넣어줬더니 0부터 6까지 총 7개 원소를 가진 문자열배열을 리턴해줬어요.
limit에 양수값을 넣어줬을 때에는 문자열을 limit개수만큼 분리해줍니다.
반면 마이너스이면 처음부터 끝까지 결과가 빈문자열인 것까지 다 포함한 파싱 결과를 리턴해줍니다.
다음 시간에는 StringTokenizer에 대해 진행해볼텐데요,
둘 다 모두 문자열 파싱하는데 사용할 수 있습니다.
선행학습(?)으로 간단한 차이만 짚고 넘어가보도록 할게요.
■ 먼저 가장 큰 차이점은 split는 String클래스에 속해있는 메소드이고 StringTokenizer는 java.util에 포함되어 있는 클래스입니다.
■ split는 정규표현식으로 구분하고 StringTokenizer는 문자로 구분합니다.
■ 앞에서 확인했듯이 split는 빈문자열을 토큰으로 인식하는 반면 StringTokenizer는 빈 문자열을 토큰으로 인식하지 않는 차이점도 있어요.
■ split는 결과 값이 문자열 배열이지만, stringtokenizer는 문자열입니다. (반복문으로 계속 이어서 분리해서 반환하는거)
■ 배열에 담아 반환하는 스플리트는 데이터를 바로바로 잘라서 반환해주는 스트링토크나이져보다 성능이 약간 뒤쳐지겠죠? 그러나 데이터양이 많은 경우 거기서 거기기 때문에 크게 신경쓸 필요는 없습니다.