[출처 : http://bbs.python.or.kr/viewtopic.php?p=66561&sid=d7caa9e552c40cae5c64bd0169a5d73a]

>>> a = "\uc5ec\ub7ec" 
>>> a.decode('unicode-escape') 
u'\uc5ec\ub7ec' 
>>> print a.decode('unicode-escape') 
여러 



>>> import re 
>>> re.sub(r'\\u(\w+)', lambda m: unichr(int(m.group(1), 16)), a) 
u'\uc5ec\ub7ec' 
>>> print _ 
여러  
[출처 : http://lumitech.tistory.com/entry/Python-String-Unicode-translate-function]


문자(열) 교체 함수 str.translate(), unicode.translate() 사용법

우선 일반 문자열(unicode object 아닌 문자열)부터.

str.translate(tbl,del)두개의 인자를 받는다. tbl은 0~255의 ASCII문자를 각각 대체할 문자로 만든 매핑테이블이다. 말이 테이블이지 길이 256짜리 문자열이다. 즉, ASCII코드 32인 문자(스페이스)는 매핑테이블의 32번째 글자로 바꿔주는 것이다. 따라서 tbl은 꼭 길이 256인 문자열(str object)여야 한다.

string.translate(s, tbl, del) == s.translate(tbl, del) 이다.

 

바로 예제 ㄱㄱㅅ

 

  1. #원본 문자열. \n는 개행, \t는 탭문자, \b는 앞글자를 지운다.
    tstr = """가나다\n\t\b123 4\b5\b6\babcd efgh (789) -_-+ 라마바 사2사2 文字"""

    # 원본 문자열을 프린트
    print "original:", tstr

    # 간단한 translate. 각 바이트의 첫 비트로 translate
    tbl = ""
    for cc in range(256):
       if cc < 128: tbl += "0"
       else: tbl += "1"
    print "tbl =", tbl
    print "initial bit:", tstr.translate(tbl)

 

컨트롤 캐릭터를 지우는데 활용해 보기.

 

  1. # ascii code값이 32미만(컨트롤캐릭터)이면 32(space)로 바꾸는 매핑테이블. \n \r \t \b 이런거 다 공백으로 바뀐다.
    TRMAP_ASCII_CTRL2SPACE = "".join([chr(max(32,cc)) for cc in range(256)])
    print "ctrl to space:", tstr.translate(TRMAP_ASCII_CTRL2SPACE)

    # 컨트롤 캐릭터를 공백으로 바꾸고 홀수는 지우는 변환.
    print "ctrl to space deleting '13579':", tstr.translate(TRMAP_ASCII_CTRL2SPACE, "13579")

 

컨트롤 캐릭터를 공백으로 바꾸지 않고 del인자를 써서 삭제할 수도 있다.

  1. # 아무것도 바꾸지 않는 매핑 테이블
    TRMAP_NOCHANGE = "".join([chr(cc) for cc in range(256)])

    # 컨트롤 캐릭터만 삭제
    ASCII_CTRLCHARS = "".join([chr(cc) for cc in range(32)])
    print "delete ctrl chars:", tstr.translate(TRMAP_NOCHANGE, ASCII_CTRLCHARS)

 

character code가 127이하인 문자를 삭제하는 del인자를 써서 한글, 한자, 일어 등 멀티바이트문자만 남길 수도 있다. 간단하므로 예제 코드 생략.

 

다음은 unicode.translate()

이건 사용법은 비슷하지만 두가지 차이점이 있다. 첫째, 매핑 테이블은 진짜-_-테이블이라는것. 둘째, del 인자를 주지 않는다는 것.

매핑테이블은 dict로 정의한다. 그래서 메모리를 크게 잡아먹을 수도 있다. 그래도 함수 수행자체는 뎁따 빠르므로 활용가치가 높다.

매핑 테이블을 만드는 유용한 함수를 하나 같이 소개한다.

__builtins__.zip(seq1, seq2, ... ) 함수는 리스트를 반환하는데, seq1, seq2, ... 에서 순서대로 하나씩 꺼내서 tuple로 묶은 리스트를 반환한다.

즉, zip([1,2,3], ('a', 'b', 'c')) 는 [(1,'a'), (2,'b'), (3,'c')] 를 리턴한다.

dict object는 zip의 결과를 초기화 인수로 받을 수 있도록 만들어져 있으므로, 이걸 활용하면 unicode translate 맵핑테이블을 쉽게 작성할 수 있다.

 

한글이 나타나는 unicode range가 정해져 있으므로, 한글을 공백으로 바꿔버리는 예제를 만들어 보자.

  1. # 위에서 사용한 테스트 문자열을 unicode로 바꾼다.
    utstr = unicode(tstr, "utf8")

    # unicode에서 한글이 나타나는 영역이다.
    __unicode_range_hangul = range(0xac00, 0xd7a4)
    __unicode_range_hangul_jamo1 = range(0x1100, 0x11fa)
    __unicode_range_hangul_jamo2 = range(0x3131, 0x318f)
    __unicode_range_korean = __unicode_range_hangul + __unicode_range_hangul_jamo1 + __unicode_range_hangul_jamo2

    __build_mapping_range2char = lambda r,uc: zip(r, uc * len(r)) 

    # 한글을 모두 공백으로 바꿔버리는 매핑테이블
    trmap_korean = dict(__build_mapping_range2char(__unicode_range_korean, u" "))

    print "utstr:", utstr
    print "utstr without Korean chars:", utstr.translate(trmap_korean)

 

삭제를 하려면 매핑 테이블에서 빈 문자열( u"" )을 주면 된다. __build_mapping_range2char() 람다함수를 조금 고치면 된다. 예제 생략.

[출처 : http://mygony.com/archives/1110]


utf-8 한글을 자르기 위한 함수입니다. javascript 처럼 멀티바이트 글자에 대해 1문자로 취급할 수도 있도록 했습니다. 원래대로라면 utf-8 으로 된 한글은 3byte 이지만, 익숙한 계산법을 따르기 위해서 이 함수에서는 2byte인 것처럼 취급합니다. 즉, 다음과 같습니다.

원본
한글과 English를 혼용해서 씁니다.
checkmb=true, len=10
한글과 Eng (한글=2*3 + 공백=1*1 + 영문=1*1 => 10)

checkmb=false, len=10
한글과 Englis (모두 합쳐 10자)

 $a = '한글hangul도 포함include되었습니다.';

 
/**
* cut string in utf-8
* @author gony (http://mygony.com)
* @param $str     source string
* @param $len     cut length
* @param $checkmb if this argument is true, the function treats multibyte character as two bytes. default value is false.
* @param $tail    abbreviation symbol
* @return string  processed string
*/
function strcut_utf8($str, $len, $checkmb=false, $tail='...') {
    preg_match_all('/[\xEA-\xED][\x80-\xFF]{2}|./', $str, $match);
 
    $m    = $match[0];
    $slen = strlen($str);  // length of source string
    $tlen = strlen($tail); // length of tail string
    $mlen = count($m); // length of matched characters
 
    if ($slen <= $len) return $str;
    if (!$checkmb && $mlen <= $len) return $str;
 
    $ret   = array();
    $count = 0;
 
    for ($i=0; $i < $len; $i++) {
        $count += ($checkmb && strlen($m[$i]) > 1)?2:1;
 
        if ($count + $tlen > $len) break;
        $ret[] = $m[$i];
    }
 
    return join('', $ret).$tail;
}


파라미터 설명 
String $str : 원본 문자열
Integer $len : 문자열을 자를 길이
Boolean $checkmb : 이 값을 true로 하면 한글을 영문2자와 같이 취급한다. 기본값은 false
String $tail : 생략후 붙일 줄임 기호

반환값
{String} 처리된 문자열

주의! 이 함수는 UTF-8 문자열을 다룹니다. 다른 charset 에는 적용되지 않습니다.

mb_ 계열 함수가 없는 환경을 위해서 만들어봤습니다.

거의 없을 줄 알았는데 아직도 그런 환경이 있기는 있더라구요. ^^;; 
[출처 : http://divestudy.tistory.com/8]


사실 한글 인코딩에는 관심이 없었다. 그냥 대충 처리해도 잘 보고 잘 쓸수 있기때문에??

이번에 초성검색에 대한 문제를 해결하는데 문제가 생겼다.
한글이 어떻게 저장 되있냐에 따라 초성 검색 방식이 달라지기 때문이다.
어줍잖은 지식으로 조합형으로 되있겠지라고 했지만 이게 왠걸?!
조합형으로 저장을 안하네 ㅎㄷㄷ 시스템마다 다름 윈도우는 기본적으로 euc-kr(완성형)
어쨌든 우분투에서 만들어야 하니 우분투 인코딩셋에대해서 알아본 결과
UTF-8 이란것을 알수 있었다 (locale 명령어로 알수 있음)
UTF-8 이라.. 어서 많이 들어 본 단어 인데;; 브라우져에서도 보고 파일 전송때도 보고..
알고 보니 UNICODE를 표현하는 방법 중에 하나라고 한다.(UTF-8 뿐만아니라 -16, -32 등도 있음)
어쨌든!! 이런건 인터넷에 널려 있으니 참고 하면 되고 변환 방법을 알아보자!!

유니코드는 전세계 모든언어를 표기하기위해 만들어졌지만 한글만 변환하므로 이에 관련된것만 보겠다.
"가"는 UNICODE로 AC 00 (16 진수 표기 , UAC00 라고도 표기한다 앞의 U는 유니코드를 나타낼때) 이고
U-00000800 - U-0000FFFF 범위에 들어가므로 비트 마스크(?)는 1110xxxx 10xxxxxx 10xxxxxx 이다.

즉, UTF-8로 표기시 1110xxxx 10xxxxxx 10xxxxxx 형태가 되며 x는 AC00를 순서대로 넣어주면 된다.
AC00 => 1010 1100 0000 0000 이며 차례 대로 넣어주면

11101010 10110000 10000000 로 변환된다. 이것을 16진수로 바꿔 주면 EA B0 80 이 된다.

다음으로 알아볼것은 UNICODE를 초성, 중성, 종성으로 분리하는 방법이다.

"갈"을 분리 해보자! "갈"은 유니코드로 UAC08이다.

1) 분리할 문자를 AC00으로 뺀다 ( 0xAC08 - 0xAC00 = 0x8)
2) 1의 결과를 21로 나누고 28로 나눈 몫은 초성이다. (8/21/28 = 0)
3) 1의 결과를 21*28로 나눈 나머지와 28로 나눈 몫은 중성이다 ( (8 % (21*28)) / 28 = 0)
4) 1의 결과를 28로 나눈 나머지는 종성이다 ( 8 % 28  = 8 )

초성은  0  중성은  0  종성은 8을 테이블에서 찾으면 된다.

초성 테이블

10  11  12  13  14  15  16  17  18 
 ㄱ  ㄲ   ㄴ  ㄷ  ㄸ  ㄹ  ㅁ  ㅂ  ㅃ  ㅅ  ㅆ  ㅇ  ㅈ   ㅉ   ㅊ   ㅋ   ㅌ   ㅍ   ㅎ 

중성 테이블
 0  1  2  3  4  5  6  7  8 10  11  12  13  14  15  16  17  18 
 ㅏ  ㅐ  ㅑ  ㅒ  ㅓ  ㅔ  ㅕ  ㅖ  ㅗ  ㅠ  ㅘ ㅛ   ㅙ  ㅚ  ㅜ  ㅝ  ㅞ  ㅟ  ㅡ
 19 20 
 ㅢ  ㅣ  

종성 테이블
 0  1  2  3  4  5  6  7  8 10  11  12  13  14   15  16  17  18
   ㄱ  ㄴ  ㄵ  ㄶ  ㄷ   ㄹ   ㄺ   ㄻ   ㄼ  ㄽ  ㄾ  ㄿ  ㅀ   ㅁ  ㅂ  ㅄ 
19  20  21  22  23  24  25  26  27
ㅅ  ㅆ  ㅇ   ㅈ  ㅊ  ㅋ   ㅌ  ㅍ  ㅎ 


"ㄱ" + "ㅏ" + "ㄹ" 인걸 알수 있다11 이젠 초성 검색 ㄱㄱ씽!!!

+ Recent posts