package kr.kangwoo.util.hangul; import java.util.HashMap; import java.util.Map; /** *

À¯´ÏÄÚµå(Unicode) ±â¹ÝÀ¸·Î ¸¸µç ÇÑ±Û °ü·Ã Ŭ·¡½ºÀÔ´Ï´Ù.

* * *

À¯´ÏÄÚµå

*

À¯´ÏÄÚµå(Unicode)´Â Àü¼¼°èÀÇ ¸ðµç ¹®ÀÚ¸¦ ÄÄÇ»ÅÍ¿¡¼­ ÀϰüµÇ°Ô Ç¥ÇöÇÏ°í ´Ù·ê ¼ö ÀÖµµ·Ï ¼³°èÇÑ Ç¥ÁØÀÔ´Ï´Ù. *

* *

Unicode Korean specific

* * *

À¯´ÏÄڵ忡¼­ÀÇ ÇѱÛ

*

À¯´ÏÄÚµå CharacterSet¿¡¼­ ÇѱÛÀÌ Â÷ÁöÇÏ´Â ¿µ¿ªÀº ¼¼ °³·Î ³ª´­ ¼ö ÀÖ½À´Ï´Ù. * ù¹øÂ°´Â 0x1100-0x11F9 ±îÁöÀÇ ÇÑ±Û Àڸ𠿵¿ª. Çѱۿ¡¼­ »ç¿ëµÇ´Â ÀÚ¸ðµéÀ» Ãʼº ÀÚÀ½/Áß¼º ¸ðÀ½/Á¾¼º ÀÚÀ½À¸·Î °¢°¢ ³ª´©¾î ÇѱÛÀÚ¾¿ ´ëÀÀ½Ãŵ´Ï´Ù. * ÀÌ ¿µ¿ª¿¡ ÀÖ´Â ±ÛÀÚµéÀ» ÀÌ¿ëÇϸé ÇÑ±Û °í¾î±îÁö Ç¥ÇöÀÌ °¡´ÉÇØÁý´Ï´Ù. ij¸¯Åͼ º¯È¯ÀÌ ¾î·Æ´Ù´Â ´ÜÁ¡ÀÌ ÀÖ½À´Ï´Ù. * µÎ¹øÂ°´Â 0x3130-0x318E ±îÁöÀÇ ÇÑ±Û È£È¯ Àڸ𠿵¿ª. ÀÌ ºÎºÐÀº ÃÊ/Áß/Á¾¼ºÀ» ±¸ºÐÇÏÁö ¾Ê°í ±×³É »ç¿ëµÇ´Â ¸ðµç ÀÚ¸ðµéÀÌ Çѵ¥ ¹­¿© µé¾î ÀÖ½À´Ï´Ù. * ¼¼¹øÂ°´Â 0xAC00-0xD7A3 ±îÁöÀÇ ÇÑ±Û ¿µ¿ª. ÀÌ ºÎºÐ¿¡´Â Çö´ë ÇÑ±Û ÀÚ¸ð·Î Ç¥Çö °¡´ÉÇÑ ¸ðµç ÇÑ±Û ¹®ÀÚµé(11172ÀÚ=19*21*28))ÀÌ µé¾î ÀÖ½À´Ï´Ù. * °£´ÜÇÑ °è»êÀ» ÅëÇØ Àڸ𸦠ÃßÃâÇÏ´Â °ÍÀÌ °¡´ÉÇÕ´Ï´Ù. * ±× ¿Ü ÇÑÀÚµéÀº ´Ù¸¥ ¿µ¿ª¿¡ Æ÷ÇԵǾî ÀÖ½À´Ï´Ù.

* *

ÀÚ¸ð À¯Çü

* * *

ÃÊ/Áß/Á¾¼º ÃßÃâÇϱâ

* * *

Âü°í ÀÚ·á

* * * * @author kangwoo * @version 1.0 * @since 1.0 */ public class Hangul { private static final char HANGUL_SYLLABLES_BEGIN = 0xAC00; private static final char HANGUL_SYLLABLES_END = 0xD7A3; private static final char HANGUL_COMPATIBILITY_JAMO_BEGIN = 0x3130; private static final char HANGUL_COMPATIBILITY_JAMO_END = 0x318E; private static final char HANGUL_COMPATIBILITY_JA_BEGIN = 0x3130; private static final char HANGUL_COMPATIBILITY_JA_END = 0x314E; private static final char HANGUL_COMPATIBILITY_MO_BEGIN = 0x314F; private static final char HANGUL_COMPATIBILITY_MO_END = 0x3163; private static final char HANGUL_JAMO_BEGIN = 0x1100; private static final char HANGUL_JAMO_END = 0x11F9; /** * '¤¡', '¤¢', '¤¤', '¤§', '¤¨', '¤©', '¤±', '¤²', '¤³', '¤µ', '¤¶', '¤·', '¤¸', '¤¹', '¤º', '¤»', '¤¼', '¤½', '¤¾' */ private static final char[] HANGUL_CHOSEONG = {0x3131, 0x3132, 0x3134, 0x3137, 0x3138, 0x3139, 0x3141, 0x3142, 0x3143, 0x3145, 0x3146, 0x3147, 0x3148, 0x3149, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e}; /** * '¤¿', '¤À', '¤Á', '¤Â', '¤Ã', '¤Ä', '¤Å', '¤Æ', '¤Ç', '¤È', '¤É', '¤Ê', '¤Ë', '¤Ì', '¤Í', '¤Î', '¤Ï', '¤Ð', '¤Ñ', '¤Ò', '¤Ó' */ private static final char[] HANGUL_JUNGSEONG = {0x314f, 0x3150, 0x3151, 0x3152, 0x3153, 0x3154, 0x3155, 0x3156, 0x3157, 0x3158, 0x3159, 0x315a, 0x315b, 0x315c, 0x315d, 0x315e, 0x315f, 0x3160, 0x3161, 0x3162, 0x3163}; /** * ' ', '¤¡', '¤¢', '¤£', '¤¤', '¤¥', '¤¦', '¤§', '¤©', '¤ª', '¤«', '¤¬', '¤­', '¤®', '¤¯', '¤°', '¤±', '¤²', '¤´', '¤µ', '¤¶', '¤·', '¤¸', '¤º', '¤»', '¤¼', '¤½', '¤¾' */ private static final char[] HANGUL_JONGSEONG = {0x0000, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137, 0x3139, 0x313a, 0x313b, 0x313c, 0x313d, 0x313e, 0x313f, 0x3140, 0x3141, 0x3142, 0x3144, 0x3145, 0x3146, 0x3147, 0x3148, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e}; public static final int HANGUL_CHOSEONG_SIZE = HANGUL_CHOSEONG.length; // 19 public static final int HANGUL_JUNGSEONG_SIZE = HANGUL_JUNGSEONG.length; // 21 public static final int HANGUL_JONGSEONG_SIZE = HANGUL_JONGSEONG.length; // 28 private static final Map HANGUL_CHOSEONG_CODE_TABLE = new HashMap(); private static final Map HANGUL_JUNGSEONG_CODE_TABLE = new HashMap(); private static final Map HANGUL_JONGSEONG_CODE_TABLE = new HashMap(); static { for (int i = 0; i < HANGUL_CHOSEONG.length; i++) { HANGUL_CHOSEONG_CODE_TABLE.put(HANGUL_CHOSEONG[i], i); } for (int i = 0; i < HANGUL_JUNGSEONG.length; i++) { HANGUL_JUNGSEONG_CODE_TABLE.put(HANGUL_JUNGSEONG[i], i); } for (int i = 0; i < HANGUL_JONGSEONG.length; i++) { HANGUL_JONGSEONG_CODE_TABLE.put(HANGUL_JONGSEONG[i], i); } } /** *

ÀÔ·ÂÇÑ ¹®ÀÚ°¡ ÇѱÛÀÎÁö ÆÇ´ÜÇÑ´Ù.

*

(Äڵ尪ÀÌ ÇÑ±Û ¿µ¿ª(0xAC00-0xD7A3)ÀÎÁö ÆÇ´Ü)

* * @param c * @return ÇѱÛÀ̸é true, ¾Æ´Ï¸é false */ public static boolean isHangulSyllables(char ch) { return ch >= HANGUL_SYLLABLES_BEGIN && ch <= HANGUL_SYLLABLES_END; } /** *

ÀÔ·ÂÇÑ ¹®ÀÚ°¡ ÇÑ±Û È£È¯ ÀÚ¸ðÀÎÁö ÆÇ´ÜÇÑ´Ù.

*

(Äڵ尪ÀÌ ÇÑ±Û È£È¯ Àڸ𠿵¿ª(0x1100-0x318E)ÀÎÁö ÆÇ´Ü)

* * @param ch * @return ÇÑ±Û È£È¯ ÀÚ¸ðÀ̸é true, ¾Æ´Ï¸é false */ public static boolean isHangulCompatibilityJamo(char ch) { return ch >= HANGUL_COMPATIBILITY_JAMO_BEGIN && ch <= HANGUL_COMPATIBILITY_JAMO_END; } /** *

ÀÔ·ÂÇÑ ¹®ÀÚ°¡ ÇÑ±Û È£È¯ ¿µ¿ª Áß Çö´ë ÀÚÀ½ÀÎÁö ÆÇ´ÜÇÑ´Ù.

*

(Äڵ尪ÀÌ ÇÑ±Û È£È¯ Àڸ𠿵¿ªÁß Çö´ë ÀÚÀ½(0x3130-0x314E)ÀÎÁö ÆÇ´Ü)

* * @param ch * @return */ public static boolean isHangulCompatibilityJa(char ch) { return ch >= HANGUL_COMPATIBILITY_JA_BEGIN && ch <= HANGUL_COMPATIBILITY_JA_END; } /** *

ÀÔ·ÂÇÑ ¹®ÀÚ°¡ ÇÑ±Û È£È¯ ¿µ¿ªÁß Çö´ë ¸ðÀ½ÀÎÁö ÆÇ´ÜÇÑ´Ù.

*

(Äڵ尪ÀÌ ÇÑ±Û È£È¯ Àڸ𠿵¿ªÁß Çö´ë ¸ðÀ½(0x314F-0x3163)ÀÎÁö ÆÇ´Ü)

* * @param ch * @return */ public static boolean isHangulCompatibilityMo(char ch) { return ch >= HANGUL_COMPATIBILITY_MO_BEGIN && ch <= HANGUL_COMPATIBILITY_MO_END; } /** *

ÀÔ·ÂÇÑ ¹®ÀÚ°¡ ÇÑ±Û ÀÚ¸ðÀÎÁö ÆÇ´ÜÇÑ´Ù.

*

(Äڵ尪ÀÌ ÇÑ±Û Àڸ𠿵¿ª(0x3130-0x11F9)ÀÎÁö ÆÇ´Ü)

* * @param ch * @return ÇÑ±Û ÀÚ¸ðÀ̸é true, ¾Æ´Ï¸é false */ public static boolean isHangulJamo(char ch) { return ch >= HANGUL_JAMO_BEGIN && ch <= HANGUL_JAMO_END; } /** *

ÃʼºÀ» ÃßÃâÇÑ´Ù.

* * @param ch * @return */ public static char getChoseong(char ch) { if (isHangulSyllables(ch) == false) { throw new IllegalArgumentException("ÀԷ°ªÀÌ À߸øµÇ¾ú½À´Ï´Ù. (" + ch + ")"); } int hCode = (ch - HANGUL_SYLLABLES_BEGIN) / (HANGUL_JUNGSEONG_SIZE * HANGUL_JONGSEONG_SIZE); return HANGUL_CHOSEONG[hCode]; } /** *

Áß¼ºÀ» ÃßÃâÇÑ´Ù.

* * @param ch * @return */ public static char getJungseong(char ch) { if (isHangulSyllables(ch) == false) { throw new IllegalArgumentException("ÀԷ°ªÀÌ À߸øµÇ¾ú½À´Ï´Ù. (" + ch + ")"); } int hCode = ((ch - HANGUL_SYLLABLES_BEGIN) % (HANGUL_JUNGSEONG_SIZE * HANGUL_JONGSEONG_SIZE)) / HANGUL_JONGSEONG_SIZE; return HANGUL_JUNGSEONG[hCode]; } /** *

Á¾¼ºÀ» ÃßÃâÇÑ´Ù.

* * @param ch * @return */ public static char getJongseong(char ch) { if (isHangulSyllables(ch) == false) { throw new IllegalArgumentException("ÀԷ°ªÀÌ À߸øµÇ¾ú½À´Ï´Ù. (" + ch + ")"); } int hCode = ((ch - HANGUL_SYLLABLES_BEGIN) % (HANGUL_JUNGSEONG_SIZE * HANGUL_JONGSEONG_SIZE)) % HANGUL_JONGSEONG_SIZE; return HANGUL_JONGSEONG[hCode]; } /** *

ÃÊ/Áß/Á¾¼ºÀ» ÃßÃâÇÑ´Ù. *

* @param ch * @return [Ãʼº, Áß¼º, Á¾¼º] or [Ãʼº, Áß¼º] */ public static char[] getJamo(char ch) { char[] jamo = new char[3]; jamo[0] = getChoseong(ch); jamo[1] = getJungseong(ch); jamo[2] = getJongseong(ch); if (jamo[2] == HANGUL_JONGSEONG[0]) { char[] temp = new char[2]; temp[0] = jamo[0]; temp[1] = jamo[1]; jamo = temp; } return jamo; } /** *

Á¾¼ºÀÌ Á¸ÀçÇÏ´ÂÁö ¿©ºÎ¸¦ ÆÇ´ÜÇÑ´Ù.

* * @param ch * @return Á¾¼ºÀÌ Á¸ÀçÇϸé true, ¾Æ´Ï¸é false */ public static boolean hasJongseong(char ch) { return getJongseong(ch) != HANGUL_JONGSEONG[0]; } /** *

Ãʼº, Áß¼ºÀ» °ãÇÕÇÏ¿© ÇѱÛÀÚ·Î ¸¸µç´Ù.

* * @param choseong Ãʼº * @param jungseong Áß¼º * @return */ public static char toHangul(char choseong, char jungseong) { return toHangul(choseong, jungseong, HANGUL_JONGSEONG[0]); } /** *

Ãʼº, Áß¼º, Á¾¼ºÀ» °áÇÕÇÏ¿© ÇѱÛÀÚ·Î ¸¸µç´Ù.

* * @param choseong Ãʼº * @param jungseong Áß¼º * @param jongseong Á¾¼º * @return */ public static char toHangul(char choseong, char jungseong, char jongseong) { Integer choseongIndex = HANGUL_CHOSEONG_CODE_TABLE.get(choseong); if (choseongIndex == null) { throw new IllegalArgumentException("ÃʼºÀÌ À߸øµÇ¾ú½À´Ï´Ù. (" + choseong + ")"); } Integer jungseongIndex = HANGUL_JUNGSEONG_CODE_TABLE.get(jungseong); if (jungseongIndex == null) { throw new IllegalArgumentException("Áß¼ºÀÌ À߸øµÇ¾ú½À´Ï´Ù. (" + jungseong + ")"); } if (jongseong == ' ') { jongseong = HANGUL_JONGSEONG[0]; } Integer jongseongIndex = HANGUL_JONGSEONG_CODE_TABLE.get(jongseong); if (jongseongIndex == null) { throw new IllegalArgumentException("Á¾¼ºÀÌ À߸øµÇ¾ú½À´Ï´Ù. (" + jongseong + ")"); } return (char)(HANGUL_SYLLABLES_BEGIN + (choseongIndex * (HANGUL_JUNGSEONG_SIZE * HANGUL_JONGSEONG_SIZE)) + (jungseongIndex * HANGUL_JONGSEONG_SIZE) + jongseongIndex); } /** *

±ÛÀÚ¿¡ ¾Ë¸Â´Â Á¶»ç¸¦ ¼±ÅÃÇÑ´Ù.

* *
	 * Hangul.getJosa('ÇÑ', 'Àº', '´Â') = 'Àº'
	 * Hangul.getJosa('Áö', 'ÀÌ', '°¡') = '°¡'
	 * 
* * @param ch * @param aux1 Á¾¼ºÀÌ ÀÖÀ»¶§ ºÙÀÏ Á¶»ç * @param aux2 Á¾¼ºÀÌ ¾øÀ»¶§ ºÙÀÏ Á¶»ç * @return */ public static char getJosa(char ch, char aux1, char aux2) { return hasJongseong(ch) ? aux1 : aux2; } /** *

±ÛÀÚ¿¡ ¾Ë¸Â´Â Á¶»ç¸¦ ¼±ÅÃÇÑ´Ù.

* *
	 * Hangul.getJosa('ÇÑ', "Àº", "´Â") = "Àº"
	 * Hangul.getJosa('Áö', "ÀÌ", "°¡") = "°¡"
	 * 
* * @param ch * @param aux1 Á¾¼ºÀÌ ÀÖÀ»¶§ ºÙÀÏ Á¶»ç * @param aux2 Á¾¼ºÀÌ ¾øÀ»¶§ ºÙÀÏ Á¶»ç * @return */ public static String getJosa(char ch, String aux1, String aux2) { return hasJongseong(ch) ? aux1 : aux2; } }