개발자 포럼

필독사항1 :  
필독사항2 :  


문자메세지 내용을 80바이트에 맞춰서 자를려면 단순히 substr 함수로는 자를 수가 없습니다. 완성형 한글의 경우 한글은 2바이트로 영어는 1바이트로 구성되기 때문에 단순히 substr($str, 0, 80)으로 자르면 끝에 위치하는 값에 따라서 재수가 나쁘면 한글이 깨지는 경우가 발생합니다. 


완성형 한글로 인코딩된 문자열은 각 캐릭터를 십진수로 변환하여 128 보다 작으면 영문이고 128 이상의 값이면 한글로 구별할 수 있었는데요.


- 완성형 한글 자르기

     function strcut_euckr($msg, $limit) 
    {
        $msg = substr($msg, 0, $limit);

        for ($i = $limit - 1; $i > 1; $i--) 
        {     
            if (ord(substr($msg,$i,1)) < 128) break;
        }

        $msg = substr($msg, 0, $limit - ($limit - $i + 1) % 2);

        return $msg;
    }


UTF-8 인코딩에서 한글코드는 3바이트로 이뤄져 있어서 취급하기 쉽지는 않은 것 같습니다.  아래 코드를 사용하시면 완성형 한글에서 사용한 한글 2바이트, 영어 1바이트 수준에 맞추어 한글을 잘라낼 수 있습니다.


- UTF-8 한글 자르기

     function strcut_utf8($str, $len, $checkmb=false, $tail='') {
        /**
         * UTF-8 Format
         * 0xxxxxxx = ASCII, 110xxxxx 10xxxxxx or 1110xxxx 10xxxxxx 10xxxxxx
         * latin, greek, cyrillic, coptic, armenian, hebrew, arab characters consist of 2bytes
         * BMP(Basic Mulitilingual Plane) including Hangul, Japanese consist of 3bytes
         **/
        preg_match_all('/[\xE0-\xFF][\x80-\xFF]{2}|./', $str, $match); // target for BMP

        $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;
    }


다음과 같이 5바이트를 잘라야하는데 완성형 한글 기준으로 봤을 때 5바이트 시작은 한글 '다'의 앞쪽코드이기 때문에 한글이 깨지지 않도록 4바이트까지만 잘라서 "가나" 문자열을 리턴합니다.


    echo strcut_utf8("가나다라마바사아자차카타파하", 5, True, "")

    가나


아래와 같이 strlen 함수도 가능합니다.


- 완성형 한글 기준 크기 알아내기

     function strlen_utf8($str, $checkmb = false) {
        preg_match_all('/[\xE0-\xFF][\x80-\xFF]{2}|./', $str, $match); // target for BMP

        $m = $match[0];
        $mlen = count($m); // length of matched characters

        if (!$checkmb) return $mlen;

        $count=0;
        for ($i=0; $i < $mlen; $i++) {
            $count += ($checkmb && strlen($m[$i]) > 1)?2:1;
        }

        return $count;
    }


위 코드들은 CTM-PHP 최신버젼에도 포함되어 있습니다.

List of Articles
번호 제목 글쓴이
» 오픈TIP [PHP] UTF-8 유니코드 한글 자르기 wiley