본문 바로가기

Native/C

UTF8 어절분리기(tokenizer) (unicode)

UTF8 어절분리기(tokenizer)

이 함수는 문서에서 어절 단위로 토큰(token)을 추출합니다. 어절의 의미를 어디까지로 해석해야 할 지는 사람마다 다를 수 있을 것입니다. 그래서 어절의 수준을 소스의 다음 부분에서 조절할 수 있습니다.

위에서는 '+'는 토큰의 구분에 들어가지 않고 나머지 모든 공백, 상징문자, 제어문자 등을 토큰의 구분자로 이용합니다. 어절 분리기의 결과를 보시려면 여기를 눌러주세요. 소스 코드는 UTF8token.c입니다.

 

 

/* by Jinsuk Kim, http://www.jinsuk.pe.kr */

#include
#include

int UTF8token(char **strPtr, char *Token, int *len)
{
    int charType = 0;
    unsigned short unicode = 0x0000;
    unsigned char c;
    int charOffset; /* how many bytes for this UTF-8 char */

    *len = 0;
    while (**strPtr) {
c = (**strPtr)&0xe0;
if (c < 0x80) {
    Token[*len] = **strPtr;
    (*len)++;
    unicode = (unsigned short) **strPtr;
}
else if (c < 0xe0) {
    Token[*len] = **strPtr;
    Token[*len+1] = *(*strPtr+1);
    (*len) += 2;
    unicode = (unsigned short) **strPtr & 0x1f;
    ++*strPtr;
    unicode = unicode << 6;
    unicode = unicode | ((unsigned short) **strPtr & 0x3f);
}
else if (c < 0xf0) {
    Token[*len] = **strPtr;
    Token[*len+1] = *(*strPtr+1);
    Token[*len+2] = *(*strPtr+2);
    (*len) += 3;
    unicode = (unsigned short) **strPtr & 0x0f;
    ++*strPtr;
    unicode = unicode << 6;
    unicode = unicode | ((unsigned short) **strPtr & 0x3f);
    ++*strPtr;
    unicode = unicode << 6;
    unicode = unicode | ((unsigned short) **strPtr & 0x3f);
}

charType = cType2[unicode];

if (unicode < 0x80) charOffset = 1;
else if (unicode < 0x0800) charOffset = 2;
else charOffset = 3;

switch(charType) {
    case T_BLN: /* blank characters */
    case T_SPC: /* special characters */
    case T_SYM: /* symbolic characters */
    case T_CTK: /* control characters */
switch( (char)unicode ) {
    case '+':
//     case '.':
//     case ',':
break;
    default:
// *strPtr -= charOffset-1; /* no need to backward ? */
*len -= charOffset;
++*strPtr;
goto escape_loop;
}
break;
    default:
break;
}
++*strPtr;
    }
escape_loop:
    Token[*len] = '\0';

    return charType;
}