한글 종성유무에 맞는 조사(은/는/이/가/을/를/과/와) 변환

조사 바로 앞의 문자에 받침(종성)이 있냐 없냐에 따라 구분되는데,

UTF-8 이라 가정하고 종성이 있는지 없는지 판단하여 적절한 조사를 치환해주는 간단한 클래스를 만들었음.

// 게임 메세지라 가정하고 치환하는 예제
$name   = '백충덕';
$monster = '고블린';
$item1 = '포션';
$item2 = '엘릭서';

$str = '몬스터 '.$monster.'{가} 나타났다.'."\n";
$str .= $name.'{은} '.$monster.'{를} 물리치고 '.$item1.'{와} '.$item2.'{를} 얻었다.'."\n";
echo Postposition::conv($str);
// 출력
// 몬스터 고블린이 나타났다.
// 백충덕은 고블린을 물리치고 포션과 엘릭서를 얻었다.


// 조사 치환 함수
// 치환대상 조사를 {가},{은} 식으로 감싼 문자을 넘기면 알아서 변환해 줌.
class Postposition
{
    // 조사 리스트
    // 0,2,4,6 = 종성있음
    // 1,3,5,7 = 종성없음
    const POSTPOSITION_LIST = '이가은는을를과와';

    // 인스턴스
    private static $instance = null;

    // 문장에서 조사를 적절하게 변환
    public static function conv($str)
    {
        return self::getInstance()->__conv($str);
    }

    // 인스턴스 반환
    private static function getInstance()
    {
        if (self::$instance === null) self::$instance = new self;

        return self::$instance;
    }

    // 생성자. internal encoding 세팅
    private function __construct()
    {
        mb_internal_encoding('UTF-8');
    }

    // 조사 변환
    private function __conv($str)
    {
        return preg_replace_callback("/(.)\\{([".self::POSTPOSITION_LIST."])\\}/u", array($this, 'replace'), $str);
    }

    // preg_replace_callback의 callback함수
    private function replace($matches)
    {
        // 조사 바로 앞 한글자
        $lastChar = $matches[1];
        // 조사
        $postpositionMatched = $matches[2];

        // 종성 유/무에 따른 조사배열 세팅
        $arrPostposition = array(
            '종성없음' => $postpositionMatched,
            '종성있음' => $postpositionMatched
        );
        $pos = mb_strpos(self::POSTPOSITION_LIST, $postpositionMatched);
        if ($pos % 2 != 0) {
            $arrPostposition['종성있음'] = mb_substr(self::POSTPOSITION_LIST, $pos-1, 1);
        } else {
            $arrPostposition['종성없음'] = mb_substr(self::POSTPOSITION_LIST, $pos+1, 1);
        }

        // 기본값 = '종성있음'
        $lastCharStatus = '종성있음';

        // 2바이트 이상 유니코드 문자
        if (strlen($lastChar) > 1) {
            $code = $this->utf8Ord($lastChar) - 44032;

            // 한글일 경우 (가=0, 힣=11171)
            if ($code > -1 && $code < 11172) {
                // 초성
                //$code / 588
                // 중성
                //$code % 588 / 28
                // 종성
                if ($code % 28 == 0) $lastCharStatus = '종성없음';
            }
        // 1바이트 ASCII
        } else {
            // 숫자중 2(이),4(사),5(오),9(구)는 종성이 없음
            if (strpos('2459', $lastChar) > -1) {
                $lastCharStatus = '종성없음';
            }
        }

        // 종성 상태에 알맞는 조사를 붙여 반환
        return $lastChar.$arrPostposition[$lastCharStatus];
    }

    // ord() UTF-8 버전
    private function utf8Ord($char)
    {
        switch (strlen($char)) {
            case 1:
                return ord($char);
                break;
            case 2:
                return ((ord($char[0]) & 0x1F) << 6) | (ord($char[1]) & 0x3F);
                break;
            case 3:
                return ((ord($char[0]) & 0x0F) << 12) | ((ord($char[1]) & 0x3F) << 6) | (ord($char[2]) & 0x3F);
                break;
            case 4:
                return ((ord($char[0]) & 0x07) << 18) | ((ord($char[1]) & 0x3F) << 12) | ((ord($char[2]) & 0x3F) << 6) | (ord($char[3]) & 0x3F);
                break;
            default:
                return $char;
        }
    }
}


 

0
0
이 글을 페이스북으로 퍼가기 이 글을 트위터로 퍼가기 이 글을 카카오스토리로 퍼가기 이 글을 밴드로 퍼가기

PHP

번호 제목 글쓴이 날짜 조회수
16 PhpSpreadsheet 설정 샘플 코드 관리자 06-21 231
15 PHP & JavaScript 엑셀 파일 다운로드 및 업로드 구현 (PhpSpreadsheet 사용) 관리자 06-21 225
14 PHP 스크립트에서 JSON 반환하기 관리자 11-26 2,481
13 PhpSpreadsheet 설치 및 사용법 정리 관리자 11-07 484
12 PHP 프로그램에서 BULK INSERT 문장을 만드는 방법 관리자 07-07 490
11 PHP 문자 암호화하여 Form 전송하기 관리자 07-07 470
10 전화번호 체크하기(휴대전화, 유선, 대표번호 등등) 관리자 07-03 424
9 get vimeo thumb 관리자 04-14 436
8 PHP 에서 MySQL 사용하기 (연결, DB&테이블 생성, 데이터 삽입/선택) 관리자 04-13 567
7 [PHP] 특정 영역 자동 스크린샷 저장 후 가장 최신 이미지 DB 저장 관리자 03-15 500
6 GD PHP TEXT ALIGN 한글 관리자 03-14 416
5 [PHP] 이미지파일에 텍스트 넣기 (라이브러리) 관리자 03-12 728
4 PHP 이미지 워터마크(텍스트&이미지) 삽입하기 관리자 03-11 413
3 한글 종성유무에 맞는 조사(은/는/이/가/을/를/과/와) 변환 관리자 06-22 652
2 한국어 조사 처리 함수 관리자 04-08 737
1 PHP 에서 callback 함수를 이용하여서 mysql select row 함수 개발하는 방법 관리자 10-22 907