■ 한글 문자열 확장 처리 기능 사용하기

------------------------------------------------------------------------------------------------------------------------


TestProject.zip


KoreanStringExtension.cs

 

 

using System.Collections.Generic;

using System.Text;

 

namespace TestProject

{

    /// <summary>

    /// 한국어 문자열 확장

    /// </summary>

    public static class KoreanStringExtension

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Interface

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 한국어 문자열 인터페이스 - IKoreanString

 

        /// <summary>

        /// 한국어 문자열 인터페이스

        /// </summary>

        public interface IKoreanString

        {

            //////////////////////////////////////////////////////////////////////////////////////////////////// Method

 

            #region 한국어 매칭 문자열 구하기 - GetKoreanMatchingString(source, keyword)

 

            /// <summary>

            /// 한국어 매칭 문자열 구하기

            /// </summary>

            /// <param name="source">소스 문자열</param>

            /// <param name="keyword">키워드</param>

            /// <returns>한국어 매칭 문자열</returns>

            string GetKoreanMatchingString(string source, string keyword);

 

            #endregion

            #region 한국어 매칭 문자열 인덱스 구하기 - GetKoreanMatchingStringIndex(source, keyword)

 

            /// <summary>

            /// 한국어 매칭 문자열 인덱스 구하기

            /// </summary>

            /// <param name="source">소스 문자열</param>

            /// <param name="keyword">키워드</param>

            /// <returns>한국어 매칭 문자열 인덱스</returns>

            int GetKoreanMatchingStringIndex(string source, string keyword);

 

            #endregion

            #region 한국어 동일 여부 구하기 - EqualKorean(source, keyword)

 

            /// <summary>

            /// 한국어 동일 여부 구하기

            /// </summary>

            /// <param name="source">소스 문자</param>

            /// <param name="keyword">키워드 문자</param>

            /// <returns>한국어 동일 여부</returns>

            bool EqualKorean(char source, char keyword);

 

            #endregion

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Class

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 기정의 문자열 매칭자 - PredefinedStringMatcher

 

        /// <summary>

        /// 기정의 문자열 매칭자

        /// </summary>

        public static class PredefinedStringMatcher

        {

            //////////////////////////////////////////////////////////////////////////////////////////////////// Field

            ////////////////////////////////////////////////////////////////////////////////////////// Static

            //////////////////////////////////////////////////////////////////////////////// Field

 

            #region Field

 

            /// <summary>

            /// 디폴트

            /// </summary>

            public static GetKoreanMatchingStringDelegate Default = GetMatchingString;

 

            /// <summary>

            /// 자모

            /// </summary>

            public static GetKoreanMatchingStringDelegate Jamo = GetMatchingString;

 

            #endregion

 

            //////////////////////////////////////////////////////////////////////////////////////////////////// Method

            ////////////////////////////////////////////////////////////////////////////////////////// Static

            //////////////////////////////////////////////////////////////////////////////// Private

 

            #region 매칭 문자열 구하기 - GetMatchingString(source, keyword)

 

            /// <summary>

            /// 매칭 문자열 구하기

            /// </summary>

            /// <param name="source">소스 문자열</param>

            /// <param name="keyword">키워드</param>

            /// <returns>매칭 문자열</returns>

            private static string GetMatchingString(string source, string keyword)

            {

                if(source.GetKoreanIndex(keyword) == -1)

                {

                    return null;

                }

                else

                {

                    return source.Substring(source.GetKoreanIndex(keyword), keyword.Length);

                }

            }

 

            #endregion

        }

 

        #endregion

        #region 기정의 문자열 인덱스 발견자 - PredefinedStringIndexFinder

 

        /// <summary>

        /// 기정의 문자열 인덱스 발견자

        /// </summary>

        public static class PredefinedStringIndexFinder

        {

            //////////////////////////////////////////////////////////////////////////////////////////////////// Field

            ////////////////////////////////////////////////////////////////////////////////////////// Static

            //////////////////////////////////////////////////////////////////////////////// Public

 

            #region Field

 

            /// <summary>

            /// 디폴트

            /// </summary>

            public static GetKoreanMatchingStringIndexDelegate Default = GetMatchingStringIndex;

 

            /// <summary>

            /// 자모

            /// </summary>

            public static GetKoreanMatchingStringIndexDelegate Jamo = GetMatchingStringIndex;

 

            #endregion

 

            //////////////////////////////////////////////////////////////////////////////////////////////////// Method

            ////////////////////////////////////////////////////////////////////////////////////////// Static

            //////////////////////////////////////////////////////////////////////////////// Private

 

            #region 매칭 문자열 인덱스 구하기 - GetMatchingStringIndex(source, keyword)

 

            /// <summary>

            /// 매칭 문자열 인덱스 구하기

            /// </summary>

            /// <param name="source">소스 문자열</param>

            /// <param name="keyword">키워드</param>

            /// <returns>매칭 문자열 인덱스</returns>

            private static int GetMatchingStringIndex(string source, string keyword)

            {

                if(keyword.Length > source.Length)

                {

                    return -1;

                }

 

                if(keyword.Length == 0)

                {

                    return 0;

                }

 

                int maximum = source.Length - keyword.Length;

 

                char firstKeyword = keyword[0];

 

                for(int i = 0; i <= maximum; i++)

                {

                    if(source[i].EqualKorean(firstKeyword) == false)

                    {

                        while(++i <= maximum && source[i].EqualKorean(firstKeyword) == false);

                    }

 

                    if(i <= maximum)

                    {

                        int startIndex = i + 1;

                        int endIndex   = startIndex + keyword.Length - 1;

 

                        for(int keywordIndex = 1; startIndex < endIndex; keywordIndex++, startIndex++)

                        {

                            if(source[startIndex].EqualKorean(keyword[keywordIndex]))

                            {

                                continue;

                            }

                            else

                            {

                                break;

                            }

                        }

 

                        if(startIndex == endIndex)

                        {

                            return i;

                        }

                    }

                }

 

                return -1;

            }

 

            #endregion

        }

 

        #endregion

        #region 기정의 문자 비교자 - PredefinedCharComparator

 

        /// <summary>

        /// 기정의 문자 비교자

        /// </summary>

        public class PredefinedCharComparator

        {

            //////////////////////////////////////////////////////////////////////////////////////////////////// Field

            ////////////////////////////////////////////////////////////////////////////////////////// Static

            //////////////////////////////////////////////////////////////////////////////// Public

 

            #region Field

 

            /// <summary>

            /// 디폴트

            /// </summary>

            public static CompareCharacterDelegate Default = CompareCharacter;

 

            /// <summary>

            /// 자모

            /// </summary>

            public static CompareCharacterDelegate Jamo = CompareCharacter;

 

            #endregion

 

            //////////////////////////////////////////////////////////////////////////////////////////////////// Method

            ////////////////////////////////////////////////////////////////////////////////////////// Static

            //////////////////////////////////////////////////////////////////////////////// Private

 

            #region 문자 비교하기 - CompareCharacter(source, keyword)

 

            /// <summary>

            /// 문자 비교하기

            /// </summary>

            /// <param name="source">소스 문자</param>

            /// <param name="keyword">키워드</param>

            /// <returns>문자 비교 결과</returns>

            private static bool CompareCharacter(char source, char keyword)

            {

                bool result = false;

 

                int jamoLevel = keyword.GetJamoLevel();

 

                switch(jamoLevel)

                {

                    case 1  : result = source.MatchLevel1Jamo(keyword); break;

                    case 2  : result = source.MatchLevel2Jamo(keyword); break;

                    default : result = (source == keyword);             break;

                }

 

                return result;

            }

 

            #endregion

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Delegate

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 한국어 매칭 문자열 구하기 대리자 - GetKoreanMatchingStringDelegate(source, keyword)

 

        /// <summary>

        /// 한국어 매칭 문자열 구하기 대리자

        /// </summary>

        /// <param name="source">소스 문자열</param>

        /// <param name="keyword">키워드</param>

        /// <returns>한국어 매칭 문자열</returns>

        public delegate string GetKoreanMatchingStringDelegate(string source, string keyword);

 

        #endregion

        #region 한국어 매칭 문자열 인덱스 구하기 대리자 - GetKoreanMatchingStringIndexDelegate(source, keyword)

 

        /// <summary>

        /// 한국어 매칭 문자열 인덱스 구하기 대리자

        /// </summary>

        /// <param name="source">소스 문자열</param>

        /// <param name="keyword">키워드</param>

        /// <returns>한국어 매칭 문자열 인덱스</returns>

        public delegate int GetKoreanMatchingStringIndexDelegate(string source, string keyword);

 

        #endregion

        #region 문자 비교하기 대리자 - CompareCharacterDelegate(source, keyword)

 

        /// <summary>

        /// 문자 비교하기 대리자

        /// </summary>

        /// <param name="source">소스 문자</param>

        /// <param name="keyword">키워드 문자</param>

        /// <returns>문자 비교 결과</returns>

        public delegate bool CompareCharacterDelegate(char source, char keyword);

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

        ////////////////////////////////////////////////////////////////////////////////////////// Staitc

        //////////////////////////////////////////////////////////////////////////////// Private

 

        #region Field

 

        /// <summary>

        /// 초성 딕셔너리

        /// </summary>

        /// <remarks>한글 호환 자모 영역에 있는 글자들을 한글 자모 영역의 초성으로 맵핑한다.</remarks>

        private static Dictionary<char, char> _chosungDictionary = new Dictionary<char, char>()

        {

            {'\x3131', '\x1100'}, // ㄱ

            {'\x3132', '\x1101'}, // ㄲ

            {'\x3134', '\x1102'}, // ㄴ

            {'\x3137', '\x1103'}, // ㄷ

            {'\x3138', '\x1104'}, // ㄸ

            {'\x3139', '\x1105'}, // ㄹ

            {'\x3141', '\x1106'}, // ㅁ

            {'\x3142', '\x1107'}, // ㅂ

            {'\x3143', '\x1108'}, // ㅃ

            {'\x3145', '\x1109'}, // ㅅ

            {'\x3146', '\x110A'}, // ㅆ

            {'\x3147', '\x110B'}, // ㅇ

            {'\x3148', '\x110C'}, // ㅈ

            {'\x3149', '\x110D'}, // ㅉ

            {'\x314A', '\x110E'}, // ㅊ

            {'\x314B', '\x110F'}, // ㅋ

            {'\x314C', '\x1110'}, // ㅌ

            {'\x314D', '\x1111'}, // ㅍ

            {'\x314E', '\x1112'}  // ㅎ

        };

 

        /// <summary>

        /// 역 초성 딕셔너리

        /// </summary>

        /// <remarks>한글 자모 영역의 초성을 한글 호환 자모 영역에 있는 글자들로 맵핑한다.</remarks>

        private static Dictionary<char, char> _reverseChosungDictionary = new Dictionary<char, char>()

        {

            { '\x1100' , '\x3131' }, // ㄱ

            { '\x1101' , '\x3132' }, // ㄲ

            { '\x1102' , '\x3134' }, // ㄴ

            { '\x1103' , '\x3137' }, // ㄷ

            { '\x1104' , '\x3138' }, // ㄸ

            { '\x1105' , '\x3139' }, // ㄹ

            { '\x1106' , '\x3141' }, // ㅁ

            { '\x1107' , '\x3142' }, // ㅂ

            { '\x1108' , '\x3143' }, // ㅃ

            { '\x1109' , '\x3145' }, // ㅅ

            { '\x110A' , '\x3146' }, // ㅆ

            { '\x110B' , '\x3147' }, // ㅇ

            { '\x110C' , '\x3148' }, // ㅈ

            { '\x110D' , '\x3149' }, // ㅉ

            { '\x110E' , '\x314A' }, // ㅊ

            { '\x110F' , '\x314B' }, // ㅋ

            { '\x1110' , '\x314C' }, // ㅌ

            { '\x1111' , '\x314D' }, // ㅍ

            { '\x1112' , '\x314E'// ㅎ

        };

 

        /// <summary>

        /// 역 중성 딕셔너리

        /// </summary>

        /// <remarks>한글 자모 영역의 중성을 한글 호환 자모 영역에 있는 글자들로 맵핑한다.</remarks>

        private static Dictionary<char, char> _reverseJoongsungDictionary = new Dictionary<char, char>()

        {

            {'\x1161','\x314F'}, // ㅏ

            {'\x1162','\x3150'}, // ㅐ

            {'\x1163','\x3151'}, // ㅑ

            {'\x1164','\x3152'}, // ㅒ

            {'\x1165','\x3153'}, // ㅓ

            {'\x1166','\x3154'}, // ㅔ

            {'\x1167','\x3155'}, // ㅕ

            {'\x1168','\x3156'}, // ㅖ

            {'\x1169','\x3157'}, // ㅗ

            {'\x116A','\x3158'}, // ㅘ

            {'\x116B','\x3159'}, // ㅙ

            {'\x116C','\x315A'}, // ㅚ

            {'\x116D','\x315B'}, // ㅛ

            {'\x116E','\x315C'}, // ㅜ

            {'\x116F','\x315D'}, // ㅝ

            {'\x1170','\x315E'}, // ㅞ

            {'\x1171','\x315F'}, // ㅟ

            {'\x1172','\x3160'}, // ㅠ

            {'\x1173','\x3161'}, // ㅡ

            {'\x1174','\x3162'}, // ㅢ

            {'\x1175','\x3163'}, // ㅣ

        };

 

        /// <summary>

        /// 역 종성 딕셔너리

        /// </summary>

        /// <remarks>한글 자모 영역의 종성을 한글 호환 자모 영역에 있는 글자들로 맵핑한다.</remarks>

        private static Dictionary<char, char> _reverseJongsungDictionary = new Dictionary<char, char>()

        {

            {'\x11A8','\x3131'}, // ㄱ

            {'\x11A9','\x3132'}, // ㄲ

            {'\x11AA','\x3133'}, // ㄱㅅ

            {'\x11AB','\x3134'}, // ㄴ

            {'\x11AC','\x3135'}, // ㄴㅈ

            {'\x11AD','\x3136'}, // ㄴㅎ

            {'\x11AE','\x3137'}, // ㄷ

            {'\x11AF','\x3139'}, // ㄹ

 

            {'\x11B0','\x313A'}, // ㄹㄱ

            {'\x11B1','\x313B'}, // ㄹㅁ

            {'\x11B2','\x313C'}, // ㄹㅂ

            {'\x11B3','\x313D'}, // ㄹㅅ

            {'\x11B4','\x313E'}, // ㄹㅌ

            {'\x11B5','\x313F'}, // ㄹㅍ

            {'\x11B6','\x3140'}, // ㄹㅎ

            {'\x11B7','\x3141'}, // ㅁ

            {'\x11B8','\x3142'}, // ㅂ

            {'\x11B9','\x3144'}, // ㅂㅅ

            {'\x11BA','\x3145'}, // ㅅ

            {'\x11BB','\x3146'}, // ㅆ

            {'\x11BC','\x3147'}, // ㅇ

            {'\x11BD','\x3148'}, // ㅈ

            {'\x11BE','\x314A'}, // ㅊ

            {'\x11BF','\x314B'}, // ㅋ

 

            {'\x11C0','\x31C'}, // ㅌ

            {'\x11C1','\x31D'}, // ㅍ

            {'\x11C2','\x31E'}, // ㅎ

        };

 

        #endregion

 

        ////////////////////////////////////////////////////////////////////////////////////////// Instance

        //////////////////////////////////////////////////////////////////////////////// Private

 

        #region Field

 

        /// <summary>

        /// 한글 음절 시작

        /// </summary>

        private const char HANGUL_SYLLABLE_START = '\xAC00';

 

        /// <summary>

        /// 한글 음절 종료

        /// </summary>

        private const char HANGUL_SYLLABLE_END = '\xD79F';

 

        /// <summary>

        /// 한글 자모 시작

        /// </summary>

        private const char HANGUL_JAMO_START = '\x1100';

 

        /// <summary>

        /// 한글 자모 종료

        /// </summary>

        private const char HANGUL_JAMO_END = '\x11FF';

 

        /// <summary>

        /// 한글 자모 모음 시작

        /// </summary>

        private const char HANGUL_JAMO_MOUM_START = '\x1161';

 

        /// <summary>

        /// 한글 자모 종성 시작

        /// </summary>

        private const char HANGUL_JAMO_JONGSUNG_START = '\x11A8';

 

        /// <summary>

        /// 한글 문자 시작

        /// </summary>

        private const char HANGUL_LETTER_START = '\x3130';

 

        /// <summary>

        /// 한글 문자 종료

        /// </summary>

        private const char HANGUL_LETTER_END = '\x318F';

 

        /// <summary>

        /// 종성 간격

        /// </summary>

        private const char CHOSUNG_INTERVAL = (char)(28 * 21);

 

        /// <summary>

        /// 중성 간격

        /// </summary>

        private const char JOONGSUNG_INTERVAL = (char)28;

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Staitc

        //////////////////////////////////////////////////////////////////////////////// Public

 

        #region 조사 추가하기 - AppendJosa(this string source, string josaAfterJongsung, string josaAfterNonJongsung)

 

        /// <summary>

        /// 조사 추가하기

        /// </summary>

        /// <param name="source">소스 문자열</param>

        /// <param name="josaAfterJongsung">받침과 함께 끝나는 단어 뒤에 붙을 조사</param>

        /// <param name="josaAfterNonJongsung">받침 없이 끝나는 단어 뒤에 붙을 조사</param>

        /// <returns>조사 추가 문자열</returns>

        public static string AppendJosa(this string source, string josaAfterJongsung, string josaAfterNonJongsung)

        {

            if(source.Trim().Length == 0)

            {

                return source;

            }

 

            char lastCharacter = source[source.Length - 1];

 

            if(lastCharacter.IsInHangulSyllableRange())

            {

                return (lastCharacter.IsCharacterLevel3()) ? source + josaAfterJongsung : source + josaAfterNonJongsung;

            }

 

            return source;

        }

 

        #endregion

        #region 조사 추가하기 - AppendJosa(source, josaType)

 

        /// <summary>

        /// 조사 추가하기

        /// </summary>

        /// <param name="source">소스 문자열</param>

        /// <param name="josaType">조사 타입</param>

        /// <remarks>

        /// EN  : 은   또는 는

        /// ER  : 을   또는 를

        /// WG  : 과   또는 와

        /// YDD : 이다 또는 다

        /// YG  : 이   또는 가

        /// </remarks>

        /// <returns>조사 추가 문자열</returns>

        public static string AppendJosa(this string source, JosaType josaType)

        {

            switch(josaType)

            {

                case JosaType.EN  : return source.AppendJosa("은"  , "는");

                case JosaType.ER  : return source.AppendJosa("을"  , "를");

                case JosaType.WG  : return source.AppendJosa("과"  , "와");

                case JosaType.YDD : return source.AppendJosa("이다", "다");

                case JosaType.YG  : return source.AppendJosa("이"  , "가");

                case JosaType.ERR : return source.AppendJosa("으로", "로");

                default           : return source;

            }

        }

 

        #endregion

 

        #region 초성 추출하기 - ExtractChosung(source)

 

        /// <summary>

        /// 초성 추출하기

        /// </summary>

        /// <param name="source">소스 문자열</param>

        /// <remarks>

        /// "한글초성".ExtractChosung()   -> "ㅎㄱㅊㅅ"

        /// "Korean초성".ExtractChosung() -> "Koreanㅊㅅ"

        /// </remarks>

        /// <returns>초성 추출 문자열</returns>

        public static string ExtractChosung(this string source)

        {

            if(source.Trim().Length == 0)

            {

                return "";

            }

 

            StringBuilder stringBuilder = new StringBuilder();

 

            for(int i = 0; i < source.Length; i++)

            {

                if(source[i].IsInHangulSyllableRange())

                {

                    char chosung = (char)((source[i] - HANGUL_SYLLABLE_START) / CHOSUNG_INTERVAL + HANGUL_JAMO_START);

 

                    stringBuilder.Append(GetChosungLetter(chosung));

                }

                else

                {

                    stringBuilder.Append(source[i]);

                }

            }

 

            return stringBuilder.ToString();

        }

 

        #endregion

 

        #region 한국어 매칭 문자열 구하기 - GetKoreanMatchingString(source, keyword, getKoreanMatchingStringDelegate)

 

        /// <summary>

        /// 한국어 매칭 문자열 구하기

        /// </summary>

        /// <param name="source">소스 문자열</param>

        /// <param name="keyword">키워드</param>

        /// <param name="getKoreanMatchingStringDelegate">매칭 문자열 구하기 대리자</param>

        /// <returns>한국어 매칭 문자열</returns>

        public static string GetKoreanMatchingString(this string source, string keyword,

            GetKoreanMatchingStringDelegate getKoreanMatchingStringDelegate)

        {

            return getKoreanMatchingStringDelegate(source, keyword);

        }

 

        #endregion

        #region 한국어 매칭 문자열 구하기 - GetKoreanMatchingString(source, keyword)

 

        /// <summary>

        /// 한국어 매칭 문자열 구하기

        /// </summary>

        /// <param name="source">소스 문자열</param>

        /// <param name="keyword">키워드</param>

        /// <remarks>

        /// "한글초성".Matches("ㅊㅅ") -> "초성"

        /// "한글초성".Matches("초서") -> "초성"

        /// </remarks>

        /// <returns>한국어 매칭 문자열</returns>

        public static string GetKoreanMatchingString(this string source, string keyword)

        {

            return source.GetKoreanMatchingString(keyword, PredefinedStringMatcher.Default);

        }

 

        #endregion

        #region 한국어 매칭 문자열 구하기 - GetKoreanMatchingString(source, keyword, koreanString)

 

        /// <summary>

        /// 한국어 매칭 문자열 구하기

        /// </summary>

        /// <param name="source">소스 문자열</param>

        /// <param name="keyword">키워드</param>

        /// <param name="koreanString">한국어 문자열 인터페이스</param>

        /// <returns>한국어 매칭 문자열</returns>

        public static string GetKoreanMatchingString(this string source, string keyword, IKoreanString koreanString)

        {

            return koreanString.GetKoreanMatchingString(source, keyword);

        }

 

        #endregion

 

        #region 한국어 동일 여부 구하기 - EqualKorean(source, keyword, getKoreanMatchingStringIndexDelegate)

 

        /// <summary>

        /// 한국어 동일 여부 구하기

        /// </summary>

        /// <param name="source">소스 문자열</param>

        /// <param name="keyword">키워드</param>

        /// <param name="getKoreanMatchingStringIndexDelegate">한국어 매칭 문자열 인덱스 구하기 대리자</param>

        /// <returns>한국어 동일 여부</returns>

        public static bool EqualKorean(this string source, string keyword,

            GetKoreanMatchingStringIndexDelegate getKoreanMatchingStringIndexDelegate)

        {

            return (source.Length == keyword.Length) && (getKoreanMatchingStringIndexDelegate(source, keyword) == 0);

        }

 

        #endregion

        #region 한국어 동일 여부 구하기 - EqualKorean(source, keyword)

 

        /// <summary>

        /// 한국어 동일 여부 구하기

        /// </summary>

        /// <param name="source">소스 문자열</param>

        /// <param name="keyword">키워드</param>

        /// <remarks>

        /// "한글초성".EqualKorean("ㅊㅅ")     -> false

        /// "한글초성".EqualKorean("ㅎㄱㅊㅅ") -> true

        /// "한글초성".EqualKorean("하글ㅊㅅ") -> true

        /// </remarks>

        /// <returns>한국어 동일 여부</returns>

        public static bool EqualKorean(this string source, string keyword)

        {

            return source.EqualKorean(keyword, PredefinedStringIndexFinder.Default);

        }

 

        #endregion

        #region 한국어 동일 여부 구하기 - EqualKorean(source, keyword, koreanString)

 

        /// <summary>

        /// 한국어 동일 여부 구하기

        /// </summary>

        /// <param name="source">소스 문자열</param>

        /// <param name="keyword">키워드</param>

        /// <param name="koreanString">한국어 문자열 인터페이스</param>

        /// <returns>한국어 동일 여부</returns>

        public static bool EqualKorean(this string source, string keyword, IKoreanString koreanString)

        {

            return (source.Length == keyword.Length) && (koreanString.GetKoreanMatchingStringIndex(source, keyword) == 0);

        }

 

        #endregion

 

        #region 한국어 포함 여부 구하기 - ContainKorean(source, keyword, getKoreanMatchingStringIndexDelegate)

 

        /// <summary>

        /// 한국어 포함 여부 구하기

        /// </summary>

        /// <param name="source">소스 문자열</param>

        /// <param name="keyword">키워드</param>

        /// <param name="getKoreanMatchingStringIndexDelegate">한국어 매칭 문자열 인덱스 구하기 대리자</param>

        /// <returns>한국어 포함 여부</returns>

        public static bool ContainKorean(this string source, string keyword,

            GetKoreanMatchingStringIndexDelegate getKoreanMatchingStringIndexDelegate)

        {

            return (getKoreanMatchingStringIndexDelegate(source, keyword) != -1);

        }

 

        #endregion

        #region 한국어 포함 여부 구하기 - ContainKorean(source, keyword)

 

        /// <summary>

        /// 한국어 포함 여부 구하기

        /// </summary>

        /// <param name="source">소스 문자열</param>

        /// <param name="keyword">키워드</param>

        /// <remarks>"한글초성".ContainKorean("ㅊㅅ") -> true</remarks>

        /// <returns>한국어 포함 여부</returns>

        public static bool ContainKorean(this string source, string keyword)

        {

            return source.ContainKorean(keyword, PredefinedStringIndexFinder.Default);

        }

 

        #endregion

        #region 한국어 포함 여부 구하기 - ContainKorean(source, keyword, koreanString)

 

        /// <summary>

        /// 한국어 포함 여부 구하기

        /// </summary>

        /// <param name="source">소스 문자열</param>

        /// <param name="keyword">키워드</param>

        /// <param name="koreanString">한국어 문자열 인터페이스</param>

        /// <returns>한국어 포함 여부</returns>

        public static bool ContainKorean(this string source, string keyword, IKoreanString koreanString)

        {

            return (koreanString.GetKoreanMatchingStringIndex(source, keyword) != -1);

        }

 

        #endregion

 

        #region 한국어 인덱스 구하기 - GetKoreanIndex(source, keyword, getKoreanMatchingStringIndexDelegate)

 

        /// <summary>

        /// 한국어 인덱스 구하기

        /// </summary>

        /// <param name="source">소스 문자열</param>

        /// <param name="keyword">키워드</param>

        /// <param name="getKoreanMatchingStringIndexDelegate">한국어 매칭 문자열 인덱스 구하기 대리자</param>

        /// <returns>한국어 인덱스</returns>

        public static int GetKoreanIndex(this string source, string keyword,

            GetKoreanMatchingStringIndexDelegate getKoreanMatchingStringIndexDelegate)

        {

            return getKoreanMatchingStringIndexDelegate(source, keyword);

        }

 

        #endregion

        #region 한국어 인덱스 구하기 - GetKoreanIndex(source, keyword)

 

        /// <summary>

        /// 한국어 인덱스 구하기

        /// </summary>

        /// <param name="source">소스 문자열</param>

        /// <param name="keyword">키워드</param>

        /// <remarks>"한글초성".GetKoreanIndex("ㅊㅅ") -> 2</remarks>

        /// <returns>한국어 인덱스</returns>

        public static int GetKoreanIndex(this string source, string keyword)

        {

            return source.GetKoreanIndex(keyword, PredefinedStringIndexFinder.Default);

        }

 

        #endregion

        #region 한국어 인덱스 구하기 - GetKoreanIndex(source, keyword, koreanString)

 

        /// <summary>

        /// 한국어 인덱스 구하기

        /// </summary>

        /// <param name="source">소스 문자열</param>

        /// <param name="keyword">키워드</param>

        /// <param name="koreanString">한국어 문자열 인터페이스</param>

        /// <returns>한국어 인덱스</returns>

        public static int GetKoreanIndex(this string source, string keyword, IKoreanString koreanString)

        {

            return koreanString.GetKoreanMatchingStringIndex(source, keyword);

        }

 

        #endregion

 

        #region 한국어 동일 여부 구하기 - EqualKorean(source, keyword, compareCharacterDelegate)

 

        /// <summary>

        /// 한국어 동일 여부 구하기

        /// </summary>

        /// <param name="source">소스 문자</param>

        /// <param name="keyword">키워드</param>

        /// <param name="compareCharacterDelegate">문자 비교 대리자</param>

        /// <returns>한국어 동일 여부</returns>

        public static bool EqualKorean(this char source, char keyword, CompareCharacterDelegate compareCharacterDelegate)

        {

            return compareCharacterDelegate(source, keyword);

        }

 

        #endregion

        #region 한국어 동일 여부 구하기 - EqualKorean(source, keyword)

 

        /// <summary>

        /// 한국어 동일 여부 구하기

        /// </summary>

        /// <param name="source">소스 문자</param>

        /// <param name="keyword">키워드</param>

        /// <remarks>

        /// '한'.KEquals("ㅎ") -> true

        /// '한'.KEquals("하") -> true

        /// </remarks>

        /// <returns>한국어 동일 여부</returns>

        public static bool EqualKorean(this char source, char keyword)

        {

            return source.EqualKorean(keyword, PredefinedCharComparator.Default);

        }

 

        #endregion

        #region 한국어 동일 여부 구하기 - EqualKorean(source, keyword, koreanString)

 

        /// <summary>

        /// 한국어 동일 여부 구하기

        /// </summary>

        /// <param name="source">소스 문자</param>

        /// <param name="keyword">키워드</param>

        /// <param name="koreanString">한국어 문자열 인터페이스</param>

        /// <returns>한국어 동일 여부</returns>

        public static bool EqualKorean(this char source, char keyword, IKoreanString koreanString)

        {

            return koreanString.EqualKorean(source, keyword);

        }

 

        #endregion

 

        #region 한국어 분리하기 - SeparateKorean(source)

 

        /// <summary>

        /// 한국어 분리하기

        /// </summary>

        /// <param name="source">소스 문자</param>

        /// <returns>분리한 한국어 문자열</returns>

        public static string SeparateKorean(this char source)

        {

            if(!source.IsInHangulSyllableRange())

            {

                return source.ToString();

            }

 

            StringBuilder stringBuilder = new StringBuilder();

 

            char chosung         = (char)(((int)source - HANGUL_SYLLABLE_START) / CHOSUNG_INTERVAL + HANGUL_JAMO_START);

            char joongsung       = (char)((((int)source - HANGUL_SYLLABLE_START) % CHOSUNG_INTERVAL) / JOONGSUNG_INTERVAL +

                                       HANGUL_JAMO_MOUM_START);

            char chosungLetter   = GetChosungLetter(chosung);

            char joongsungLetter = GetJoongsungLetter(joongsung);

 

            stringBuilder.Append(chosungLetter).Append(joongsungLetter);

 

            if(source.IsCharacterLevel3() == true)

            {

                char jongsung       = (char)((((int)source - HANGUL_SYLLABLE_START) % CHOSUNG_INTERVAL) % JOONGSUNG_INTERVAL +

                                          HANGUL_JAMO_JONGSUNG_START - 1);

                char jongsungLetter = GetJongsungLetter(jongsung);

 

                stringBuilder.Append(jongsungLetter);

            }

 

            return stringBuilder.ToString();

        }

 

        #endregion

        #region 한국어 분리하기 - SeparateKorean(source)

 

        /// <summary>

        /// 한국어 분리하기

        /// </summary>

        /// <param name="source">소스 문자열</param>

        /// <remarks>

        /// "한".SeparateKorean() -> "ㅎㅏㄴ"

        /// </remarks>

        /// <returns>분리한 한국어 문자열</returns>

        public static string SeparateKorean(this string source)

        {

            StringBuilder stringBuilder = new StringBuilder();

 

            foreach(char character in source)

            {

                stringBuilder.Append(character.SeparateKorean());

            }

 

            return stringBuilder.ToString();

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////// Private

 

        #region 범위 내 여부 구하기 - IsInRange(startCharacter, character, endCharacter)

 

        /// <summary>

        /// 범위 내 여부 구하기

        /// </summary>

        /// <param name="startCharacter">시작 문자</param>

        /// <param name="character">문자</param>

        /// <param name="endCharacter">종료 문자</param>

        /// <returns>범위 내 여부</returns>

        private static bool IsInRange(char startCharacter, char character, char endCharacter)

        {

            return (character >= startCharacter && character <= endCharacter);

        }

 

        #endregion

        #region 자모 범위 내 여부 구하기 - IsInJamoRange(source)

 

        /// <summary>

        /// 자모 범위 내 여부 구하기

        /// </summary>

        /// <param name="source">소스 문자</param>

        /// <returns>자모 범위 내 여부</returns>

        private static bool IsInJamoRange(this char source)

        {

            return IsInRange(HANGUL_JAMO_START, source, HANGUL_JAMO_END) || IsInRange(HANGUL_LETTER_START, source, HANGUL_LETTER_END);

        }

 

        #endregion

 

        #region 초성 구하기 - GetChosung(source)

 

        /// <summary>

        /// 초성 구하기

        /// </summary>

        /// <param name="source">소스 문자</param>

        /// <remarks>

        /// 예) [ㄱ] 문자 (0x3131) -> [ㄱ] 초성 (0x1100)

        /// </remarks>

        /// <returns>초성</returns>

        private static char GetChosung(this char source)

        {

            try

            {

                return _chosungDictionary[source];

            }

            catch(KeyNotFoundException)

            {

                return source;

            }

        }

 

        #endregion

        #region 초성 문자 구하기 - GetChosungLetter(source)

 

        /// <summary>

        /// 초성 문자 구하기

        /// </summary>

        /// <param name="source">소스 문자</param>

        /// <returns>초성 문자</returns>

        private static char GetChosungLetter(this char source)

        {

            try

            {

                return _reverseChosungDictionary[source];

            }

            catch(KeyNotFoundException)

            {

                return source;

            }

        }

 

        #endregion

        #region 중성 문자 구하기 - GetJoongsungLetter(source)

 

        /// <summary>

        /// 중성 문자 구하기

        /// </summary>

        /// <param name="source">소스 문자</param>

        /// <remarks>

        /// 예) [ㅏ] 중성 (0x1161) -> [ㅏ] 문자 (0x314F)

        /// </remarks>

        /// <returns>중성 문자</returns>

        private static char GetJoongsungLetter(this char source)

        {

            try

            {

                return _reverseJoongsungDictionary[source];

            }

            catch(KeyNotFoundException)

            {

                return source;

            }

        }

 

        #endregion

        #region 종성 문자 구하기 - GetJongsungLetter(source)

 

        /// <summary>

        /// 종성 문자 구하기

        /// </summary>

        /// <param name="source">소스 문자</param>

        /// <remarks>

        /// 예) [ㄱ] 종성 (0x11A8) -> [ㄱ] 문자 (0x3131)

        /// </remarks>

        /// <returns>종성 문자</returns>

        private static char GetJongsungLetter(this char source)

        {

            try

            {

                return _reverseJongsungDictionary[source];

            }

            catch(KeyNotFoundException)

            {

                return source;

            }

        }

 

        #endregion

 

        #region 한글 음절 범위 내 여부 구하기 - IsInHangulSyllableRange(source)

 

        /// <summary>

        /// 한글 음절 범위 내 여부 구하기

        /// </summary>

        /// <param name="source">소스 문자</param>

        /// <returns>한글 음절 범위 내 여부</returns>

        private static bool IsInHangulSyllableRange(this char source)

        {

            return IsInRange(HANGUL_SYLLABLE_START, source, HANGUL_SYLLABLE_END);

        }

 

        #endregion

 

        #region 문자 레벨 1 여부 구하기 - IsCharacterLevel1(source)

 

        /// <summary>

        /// 문자 레벨 1 여부 구하기

        /// </summary>

        /// <param name="source">소스 문자</param>

        /// <remarks>

        /// 초성만으로 이루어진 글자인지 판별한다.

        /// ㅀ처럼 받침 전용 글자는 false로 판정한다.

        /// </remarks>

        /// <returns>문자 레벨 1 여부</returns>

        private static bool IsCharacterLevel1(this char source)

        {

            if(source.IsInJamoRange())

            {

                source = source.GetChosung();

 

                return IsInRange('\x1100', source, '\x1112');

            }

            else

            {

                return false;

            }

        }

 

        #endregion

        #region 문자 레벨 2 여부 구하기 - IsCharacterLevel2(source)

 

        /// <summary>

        /// 문자 레벨 2 여부 구하기

        /// </summary>

        /// <param name="source">소스 문자</param>

        /// <remarks>초성 + 중성으로 이루어진 글자인지 판별한다.</remarks>

        /// <returns>문자 레벨 2 여부</returns>

        private static bool IsCharacterLevel2(this char source)

        {

            if(source.IsInHangulSyllableRange())

            {

                return (source - HANGUL_SYLLABLE_START) % JOONGSUNG_INTERVAL == 0;

            }

            else

            {

                return false;

            }

        }

 

        #endregion

        #region 문자 레벨 3 여부 구하기 - IsCharacterLevel3(source)

 

        /// <summary>

        /// 문자 레벨 3 여부 구하기

        /// </summary>

        /// <param name="source">소스 문자</param>

        /// <remarks>

        /// 초성 + 중성 + 종성으로 이루어진 글자인지 판별한다.

        /// 종성이 반드시 있어야 한다.

        /// </remarks>

        /// <returns>문자 레벨 3 여부</returns>

        private static bool IsCharacterLevel3(this char source)

        {

            return source.IsInHangulSyllableRange() && (!source.IsCharacterLevel2());

        }

 

        #endregion

 

        #region 자모 레벨 구하기 - GetJamoLevel(source)

 

        /// <summary>

        /// 자모 레벨 구하기

        /// </summary>

        /// <param name="source">소스 문자</param>

        /// <returns>자모 레벨</returns>

        private static int GetJamoLevel(this char source)

        {

            if(source.IsCharacterLevel1())

            {

                return 1;

            }

            else if(source.IsCharacterLevel2())

            {

                return 2;

            }

            else if(source.IsCharacterLevel3())

            {

                return 3;

            }

            else

            {

                return 0;

            }

        }

 

        #endregion

 

        #region 레벨 1 정규화 하기 - NormalizeLevel1(source)

 

        /// <summary>

        /// 레벨 1 정규화 하기

        /// </summary>

        /// <param name="source">소스 문자</param>

        /// <remarks>

        /// 대상 유니코드를 정규화 한다 : 가, 각, 간, 감, 공, 괔, ... -> [ㄱ]

        /// </remarks>

        /// <returns>레벨 1 정규화 문자</returns>

        private static char NormalizeLevel1(this char source)

        {

            if(source.IsInJamoRange())

            {

                return source.GetChosung();

            }

            else if(source.IsInHangulSyllableRange())

            {

                return (char)((source - HANGUL_SYLLABLE_START) / CHOSUNG_INTERVAL + HANGUL_JAMO_START);

            }

 

            return source;

        }

 

        #endregion

        #region 레벨 2 정규화 하기 - NormalizeLevel2(source)

 

        /// <summary>

        /// 레벨 2 정규화 하기

        /// </summary>

        /// <param name="source">소스 문자</param>

        /// <remarks>

        /// 대상 유니코드를 정규화 한다 : 가, 각, 간, 감, 갛, ... -> [가]

        /// </remarks>

        /// <returns>레벨 2 정규화 문자</returns>

        private static char NormalizeLevel2(this char source)

        {

            return (char)(source - ((source - HANGUL_SYLLABLE_START) % JOONGSUNG_INTERVAL));

        }

 

        #endregion

 

        #region 레벨 1 자모 매칭 여부 구하기 - MatchLevel1Jamo(source, keyword)

 

        /// <summary>

        /// 레벨 1 자모 매칭 여부 구하기

        /// </summary>

        /// <param name="source">소스 문자</param>

        /// <param name="keyword">키워드</param>

        /// <returns>레벨 1 자모 매칭 여부</returns>

        private static bool MatchLevel1Jamo(this char source, char keyword)

        {

            return source.NormalizeLevel1() == keyword.NormalizeLevel1();

        }

 

        #endregion

        #region 레벨 2 자모 매칭 여부 구하기 - MatchLevel2Jamo(source, keyword)

 

        /// <summary>

        /// 레벨 2 자모 매칭 여부 구하기

        /// </summary>

        /// <param name="source">소스 문자</param>

        /// <param name="keyword">키워드</param>

        /// <returns>레벨 2 자모 매칭 여부</returns>

        private static bool MatchLevel2Jamo(this char source, char keyword)

        {

            return source.NormalizeLevel2() == keyword;

        }

 

        #endregion

    }

}

 

 

JosaType.cs

 

 

namespace TestProject

{

    /// <summary>

    /// 조사 타입

    /// </summary>

    public enum JosaType

    {

        /// <summary>

        /// 은, 는

        /// </summary>

        EN,

 

        /// <summary>

        /// 이, 가

        /// </summary>

        YG,

 

        /// <summary>

        /// 을, 를

        /// </summary>

        ER,

 

        /// <summary>

        /// 과, 와

        /// </summary>

        WG,

 

        /// <summary>

        /// 이다, 다

        /// </summary>

        YDD,

 

        /// <summary>

        /// 으로, 로

        /// </summary>

        ERR

    }

}

 

 

Program.cs

 

 

using System;

 

namespace TestProject

{

    /// <summary>

    /// 프로그램

    /// </summary>

    class Program

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Static

        //////////////////////////////////////////////////////////////////////////////// Public

 

        #region 프로그램 시작하기 - Main()

 

        /// <summary>

        /// 프로그램 시작하기

        /// </summary>

        private static void Main()

        {

            Console.WriteLine("동해물과 백두산이".EqualKorean("ㄷㅎㅁㄱ ㅂㄷㅅㅇ")); // true

            Console.WriteLine("동해물과 백두산이".EqualKorean("도해무과 ㅂㄷㅅㅇ")); // true

            Console.WriteLine("동해물과 백두산이".EqualKorean("ㄷㅎㅁㄱ ㅂㄷㅅ"  )); // false

 

            Console.WriteLine("동해물과 백두산이".ContainKorean("ㄷㅎㅁㄱ")); // true

            

            Console.WriteLine("동해물과 백두산이".GetKoreanIndex("ㄷㅎㅁㄱ")); // 0

            Console.WriteLine("동해물과 백두산이".GetKoreanIndex("ㅂㄷㅅ"  )); // 5

            

            Console.WriteLine("동해물과 백두산이".GetKoreanMatchingString("ㄷㅎㅁㄱ")); // "동해물과"

            Console.WriteLine("동해물과 백두산이".GetKoreanMatchingString("ㅂㄷㅅ"  )); // "백두산"

            

            Console.WriteLine("동해물과 백두산이".ExtractChosung()); // "ㄷㅎㅁㄱ ㅂㄷㅅㅇ"

            

            Console.WriteLine("동해물".AppendJosa(JosaType.WG)); // "동해물과"

            Console.WriteLine("백두산".AppendJosa("이", "가"));  // "백두산이"

        }

 

        #endregion

    }

}

 

------------------------------------------------------------------------------------------------------------------------

Posted by 사용자 icodebroker
TAG

댓글을 달아 주세요