728x90
반응형
728x170
▶ 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
}
}
728x90
▶ 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
}
}
300x250
▶ 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
}
}
728x90
반응형
그리드형(광고전용)
'C# > Common' 카테고리의 다른 글
[C#/COMMON] IDisposable 헬퍼 사용하기 (0) | 2019.11.19 |
---|---|
[C#/COMMON] StringBuilder 클래스 : 확장 기능 사용하기 (0) | 2019.11.19 |
[C#/COMMON] CPU 부하 생성하기 (0) | 2019.10.16 |
[C#/COMMON] ServicePointManager 클래스 : DefaultConnectionLimit 정적 속성을 사용해 웹 요청 동시 접속 수 설정하기 (0) | 2019.10.12 |
[C#/COMMON] 사용자 계정 로그온 권한 조사하기 (0) | 2019.10.11 |
[C#/COMMON] 한글 문자열 확장 처리 기능 사용하기 (0) | 2019.10.07 |
[C#/COMMON] WebClient 클래스 : 외부 IP 주소 구하기 (0) | 2019.10.06 |
[C#/COMMON] 공백 문자열 압축하기 (0) | 2019.10.06 |
[C#/COMMON] Uri 클래스 : MakeRelativeUri 메소드를 사용해 상대 디렉토리 경로 구하기 (0) | 2019.10.06 |
[C#/COMMON] Dictionary 클래스 : 이중 키 딕셔너리 사용하기 (0) | 2019.10.06 |
[C#/COMMON] BitConverter 클래스 : 빅 엔디안(Big Endien) 바이트 배열에서 정수 구하기 (0) | 2019.10.06 |
댓글을 달아 주세요