본문 바로가기

Programming/JAVA/JSP

[펌] StringTokenizer 와 String.split()

출처 : http://www.okjsp.pe.kr/seq/32363

가끔씩 StringTokenzer를 사용해서 문자열을 분해 할 때 특정 요소의 값이 없을 경우 처리하는 것에 대한 질문을 받아서 문자열을 특정 구분자를 기준으로 분해 하는 것에 대해 정리를 해봤습니다.

jdk1.4.x를 기준으로 정리한 것입니다.

잘 못 된 부분이 있으면 지적 해주십시요.

---------------------------------------------------------------------------------------------

 특정 구분자(경계기호:Delimter)를 기준으로 문자열을 분해 할 때 흔히 사용하는 방법이 java.util.StringTokenizer를 이용해서 분해를 하거나 jdk1.4대에 새로 추가 된 java.lang.String.split(String regex)을 사용하는 방법입니다.

 

이들 둘은 "문자열에서 특정 구분자를 기준으로 문자열을 분해 한다"는 기본 기능은 같지만 그 결과는 "분해 할 문자열이 어떻게 구성이 되어 있느냐"에 따라서 서로 다른 결과값을 도출합니다.

 

예를 살펴보기 위해서 다음과 같은 가정을 하겠습니다.

  • 분해 할 문자열은 "아이디, 이름, 전자우편주소,휴대전화"로 구성 된다.
  • "아이디, 이름" 이외의 항목은 있을 수도 있고 그렇지 않을 수도 있다.
  • 각 항목을 구분하는 구분자는 ","로 한다.

1. 먼저 각 항목이 모두 존재 하는 경우를 살펴 보겠습니다. 이 경우라면 다음과 같은 형태가 될 것입니다.

  • neoburi,inkuk,neoburi@neoburi.com,019-366-5815

    이 경우는 다음과 같이 분해를 할 수 있을 것입니다.

    String str = "neoburi,inkuk,neoburi@neoburi.com,019-366-5815";

    String[] values = str.split(",");

    또는,

    StringTokenizer values = new StringTokenizer( str, "," );

    이 때에는 String.split(String regex)이나 StringTokenizer의 결과 값은 같게 나옵니다.

 

    그런데 문제는 이렇게 모든 항목이 존재하지 않는 경우가 있을 때입니다.

 

2. 일부 항목만으로 문자열이 구성 된 경우를 살펴 보겠습니다.

 

    예를 든다면 다음과 같은 값을 가질 때겠지요.

  • "아이디,이름,,전화번호" 일 경우
  • "아이디,이름,전자우편," 일 경우
  • 또는 "아이디,이름,," 일 경우

    1) "아이디,이름,,전화번호" 일 경우를 살펴 보겠습니다.

    문자열은 다음과 같이 구성이 될 것입니다.

     

    String str = "neoburi,inkuk,,019-366-5815";

     

    • String[] values = str.split(",");을 사용 할 경우 해보면 결과는 아래와 같습니다.

      for( int x = 0; x < values.length; x++ ){

          System.out.println( "문자(열) " + (x+1) + " : " + values[x] );

      }

       

      결과 :

        문자(열) 1 : neoburi

        문자(열) 2 : inkuk

        문자(열) 3 :

        문자(열) 4 : 019-366-5815

         

    • StringTokenizer tokens = new StringTokenizer( str, "," );를 사용 할 경우

      for( int x = 1; tokens.hasMoreElements(); x++ ){

          System.out.println( "문자(열) " + x + " : " + tokens.nextToken() );

      }

       

      결과 :

        문자(열) 1 : neoburi

        문자(열) 2 : inkuk

        문자(열) 3 : 019-366-5815

         

    결과와 같이 split(String regex)을 이용한 경우에는 비록 값이 존재하지 않더라고 해당 데이터가 없다는 것을 확실하게 판단을 할 수 있습니다. 즉 구분자를 기준으로 데이터가 없는 부분도 그 결과를 반환해준다는 얘기지요.

     

    그렇지만 StringTokenizer는 비록 구분자로 문자열간 구분이 되어 있더라도 구분자와 구분자 사이에 데이터가 존재하지 않으면 (",,"의 경우) 해당 데이터는 무시를 하고 실제 값이 존재하는 부분만 값을 반환합니다.

     

    두 결과 사이에는 많은 차이가 남을 볼 수 있습니다.

    2) "아이디,이름,전자우편," 일 경우

    이 역시 문자열은 다음과 같이 구성이 될 것입니다.

     

    String str = "neoburi,inkuk,neoburi@neoburi.com,";

     

    • String[] values = str.split(",");

      for( int x = 0; x < values.length; x++ ){

          System.out.println( "문자(열) " + (x+1) + " : " + values[x] );

      }

       

      결과 :

        문자(열) 1 : neoburi

        문자(열) 2 : inkuk

    • StringTokenizer tokens = new StringTokenizer( str, "," );

      for( int x = 1; tokens.hasMoreElements(); x++ ){

          System.out.println( "문자(열) " + x + " : " + tokens.nextToken() );

      }

      결과 :

        문자(열) 1 : neoburi

        문자(열) 2 : inkuk

    위에서 보는 바와 같이 분해하고자 하는 문자열의 마지막 요소가 존재하지 않을 경우 String.split(String regex)과 StringTokenizer는 같은 결과를 보여줍니다.

     

    두 결과사이에는 차이가 없음에도 불구하고 잃어 버리는 데이터가 생겼습니다. 개발자는 분명히 사용자의 정보로부터 4개의 항목을 얻어 표현을 하고 싶지만 그렇게 할 수가 없습니다. 물론 어거지로 한다면 가능은 하겠지만요.^^

     

    그러면 String.split(String regex)과 StringTokenizer를 사용 하더라고 분해하고자 하는 마지막 항목이 없을 경우는 분해 할 방법이 없을까요? 그렇지 않습니다.

     

    API를 어느정도 보신 분들이라면 아마 "그것은 이렇게 하면 되지!"라고 속으로 생각 하실 겁니다.

     

    java.lang.String클래스에는 split()메소드가 2개가 있습니다.

    • 하나는 split( String regex )이고
    • 다는 하나는 split( String regex, int limit )입니다.

String.split( String regex, int limit )를 사용해서 분해를 해보겠습니다.

    • String[] values = str.split(",", 4);

      for( int x = 0; x < values.length; x++ ){

          System.out.println( "문자(열) " + (x+1) + " : " + values[x] );

      }

       

      결과 :

        문자(열) 1 : neoburi

        문자(열) 2 : inkuk

        문자(열) 4 :

         

    비록 마지막 분해 요소의 값이 존재하지 않더라고 split( String regex, int limit )를 이용하면 고스란히 원하는 형태의 데이터를 얻는 것을 볼 수 있습니다.

  StringTokenizer의 경우는 구분자 사이에 분해할 요소의 값이 존재하지 않으면 무시하게 되어 있습니다. 완전하게 모든 요소의 값이 존재하는 경우라면 사용을 해도 되겠지만 예에서 본 바와 같이 가변적인 데이터라면 사용하기 불편한(?) 것이 사실입니다.

 

  String.split()의 경우 limit를 저정 하지 않았을 경우에는 제일 마지막에 오는 요소의 값이 없을 경우 그 요소를 무시하도록 되어 있습니다. 이 역시 데이터가 정형화 되어 있는 경우라면 사용해도 무리 없겠지만 가변요소가 존재 한다면 StringTokenizer와 크게 다를 게 없습니다.

 

  대신 limit를 지정 했을 경우 해당 숫자만큼만 분해를 합니다. limit는 분해를 한 후 얻고자 하는 String[]의 요소크기라고 보시면 됩니다.

limit가 분해하고자 하는 요소의 개수와 같거나 클 경우 요소의 개수만큼의 String[]을 되돌려 주지만, 요소의 개수보다 작을 경우 지정한 숫자만큼의 String[]으로 되돌려 줍니다.

 

  좀 더 자세히 알고 싶으신 분들은 자바 원천 소스에서 java.lang.String과 java.util.StringTokenizer를 살펴보시기 바랍니다.

 

----------------

너부리-최인국

http://www.neoburi.com

----------------

http://http://www.neoburi.com/index?part=own&act=read&main=101&sub=03&no=8&grpNo=8

    Tag
    tag는 게시물의 성격을 나타내는 키워드를 입력하는 공간입니다.
    tag는 로그인 후 사용하실 수 있습니다.

    • 좋은 정보 정말 감사드립니다.
    • 착한아빠
    • 2003-06-19 09:32:59
    • x
    • 그냥... String[] values = str.split(",", -1);
      이렇게 해주면 마지막 데이타가 비어도 처리를 해주네용..
      에공...
    • skyer9
    • 2003-06-19 09:43:57
    • x
    • 그렇군요...에공...^^
    • 너부리
    • 2003-06-19 10:49:30
    • x
    • 멋지군..
    • free
    • 2003-06-19 11:33:17
    • x
    • 구수님들 정보 감사 합니다
    • 변두리(구karnoi2)
    • 2003-06-19 11:46:16
    • x
    • 좋은정보네요... ^^
    • 김윤철
    • 2003-06-19 12:13:17
    • x
    • ^^ 감사합니다...
      참고로...루프를 돌려봤는데 StringTokenizer에 대해서 String.split(...) 함수의 실행속도가 5배 정도 느리더군요...상황에 따라서 틀리겠지만 사용목적에 따라서 적절히 선택을 해야 할 거 같습니다.
    • and32
    • 2003-06-20 16:56:20
    • x
    • 보이기엔 동일한 기능이지만...
      내부적으로 split 는 정규표현식을 사용합니다.
      따라서 많이 느리죠.
      한두번 사용한다면 별문제겠지만..
      루프를 돌면서 사용하게된다면 주의를 해야겠죠 ^^
    • skyer9
    • 2003-06-21 10:27:37
    • x
    • 예 맞는 말씀입니다.^^
    • 너부리
    • 2003-06-21 18:19:47
    • x
    • 오~ 좋은 정보 감사르~ ^o^
    • 붕냥붕
    • 2003-06-23 10:09:57
    • x
    • 문자가 ABC00|ABCDEFG 이와 같은경우에
      split로 | 를 기준으로 자를 혀고 하니까 이상하게 나와요~~
      토큰으로 자르면 정상적으로 나오고.왜 그러는걸까요?
    • czar
    • 2006-06-30 16:02:37
    • x
    • "\\|", "[|]"이렇게 분리하면 됩니다
    • mino22th
    • 2007-03-16 17:32:46
    • x
    • 좋른정보 감사합니다. 댓글까지 퍼가겠습니다.
    • 삽지리
    • 2007-04-16 10:26:03
    • x