일반 문자열 처리 - StringTokenizer 와 String.split()

황제낙엽 2008.07.08 09:43 조회 수 : 658 추천:159

sitelink1 http://www.okjsp.pe.kr/seq/32363 
sitelink2  
sitelink3  
sitelink4  
sitelink5  
sitelink6  

가끔씩 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";

 

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

 

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

 

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

    • 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

       

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

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

 

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

 

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

 

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

 

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

 

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

 

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

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

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

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

      }

       

      결과 :

      문자(열) 1 : neoburi

      문자(열) 2 : inkuk

      문자(열) 3 : neoburi@neoburi.com

       

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

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

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

    }

    결과 :

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

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

비록 마지막 분해 요소의 값이 존재하지 않더라고 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

      문자(열) 3 : neoburi@neoburi.com

      문자(열) 4 :

       

  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

 

번호 제목 글쓴이 날짜 조회 수
146 사용팁 황제낙엽 2008.07.24 698
» 문자열 처리 - StringTokenizer 와 String.split() 황제낙엽 2008.07.08 658
144 숫자의 형식화 #1(Part-1)-java.text.NumberFormat 황제낙엽 2008.07.08 715
143 숫자 에 대응 되는 문자의 형식화 #2 황제낙엽 2008.07.08 709
142 숫자 에 대응 되는 패턴의 형식화 #1 황제낙엽 2008.07.08 730
141 숫자를 통화 표기 형태로 변환하기 황제낙엽 2008.07.08 694
140 NumberFormat, DecimalFormat 사용예 황제낙엽 2008.07.08 686
139 파일의 내용을 읽어 String 객체로 만드는 함수 황제낙엽 2008.06.17 538
138 UTF형태 파일에서 BOM 제거하기 황제낙엽 2008.06.16 2542
137 불러온 txt파일의 Encoding을 알 수는 방법좀 가르쳐 주세요~ 황제낙엽 2008.06.16 623
136 FileFilter, FilenameFilter 클래스를 이용한 파일 또는 디렉토리 리스트 추출하기 황제낙엽 2008.06.16 764
135 정규식 사용예제 [2] 황제낙엽 2008.06.11 674
134 정규식 사용예제 [1] 황제낙엽 2008.06.11 729
133 StringBuffer vs String 황제낙엽 2008.06.10 485
132 작지만 강력한 HTML 파서, HtmlCleaner, html parser 황제낙엽 2008.06.10 682
131 Jericho HTML Parser 황제낙엽 2008.06.10 821
130 JTidy(HTML Parser) How to 황제낙엽 2008.06.10 777
129 NekoHTML 샘플 예제 황제낙엽 2008.06.09 605
128 YGHTML Parser 0.1.1 샘플 예제 황제낙엽 2008.06.09 622
127 HTML Paser 의 종류 황제낙엽 2008.06.09 936