개발자 포럼
필독사항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 최신버젼에도 포함되어 있습니다.