String -> Ansistring
Char -> AnsiChar
PChar -> PAnsiChar 로 변경하면 동작됨.
아래코드 참조
////////////////////////////////
unit Unit5;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
const
ChoSungTbl: Ansistring = 'ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ';
JungSungTbl: Ansistring = 'ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ';
JongSungTbl: Ansistring = ' ㄱㄲㄳㄴㄵㄶㄷㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅄㅅㅆㅇㅈㅊㅋㅌㅍㅎ';
EngChosung: Ansistring = 'r R s e E f a q Q t T d w W c z x v g ';
EngJungsung: Ansistring = 'k o i O j p u P h hkhohly n njnpnlb m mll ';
EngJongsung: Ansistring = ' r R rts swsge f frfafqftfxfvfga q qtt T d w c z x v g ';
UniCodeHangeulBase = $AC00;
UniCodeHangeulLast = $D79F;
// 한글관련
function ConvEngToHan(src: Ansistring): Ansistring;
function CutFirstHangul(src: Ansistring): Ansistring;
function DecodingEngToHan(src: Ansistring): Ansistring;
function DivChoJungJong(src: Ansistring): Ansistring;
function CharKeyCheck(c: ansichar): boolean;
function MoumCheck(c: ansichar): boolean;
function HanDiv(const Han: PAnsiChar; Han3: PAnsiChar): boolean;
function HanDivPas(const src: Ansistring; Check: integer): Ansistring;
Function GetHanType(const src: Ansistring): boolean;
implementation
/// /////////////////////////////////////////////////////////////////////////////
function MoumCheck(c: ansichar): boolean;
Begin
Result := c in ['k', 'o', 'i', 'O', 'j', 'p', 'u', 'P', 'h', 'y', 'n', 'b', 'm', 'l'];
end;
function MarkCheck(c: ansichar): boolean;
Begin
Result := c in ['@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '-', ' ', '+', '=', '{', '}', '[',
']', '|', '\', '<', '>', '.', ',', '/', '?', ':', ';', '"', ''''];
end;
function CharKeyCheck(c: ansichar): boolean;
Begin
Result := c in ['A' .. 'Z', 'a' .. 'z'];
end;
function DivChoJungJong(src: Ansistring): Ansistring;
var
i, j, l: integer;
Tmp, Res: Ansistring;
Begin
l := Length(src);
If (l < 2) or (not CharKeyCheck(src[1])) Then
Begin
Result := src[1];
Exit;
end;
Tmp := src + ' ';
{ 초성 }
i := Pos(Copy(Tmp, 1, 1), EngChosung);
If i > 0 Then
Begin
Res := Copy(Tmp, 1, 1) + ' ';
j := 2;
End
Else
Begin
Result := Tmp[1];
Exit;
End;
{ 중성 }
If (not CharKeyCheck(Tmp[j])) or (not MoumCheck(Tmp[j])) Then
Begin
Result := Res;
Exit;
End
Else
Begin
i := Pos(Copy(Tmp, j, 2), EngJungsung);
If i > 0 Then
Begin
Res := Res + Copy(Tmp, j, 2);
j := j + 2;
End
Else
Begin
Res := Res + Tmp[j] + ' ';
j := j + 1;
End;
End;
{ 종성 }
If (not(Tmp[j] in [' ', 'A' .. 'Z', 'a' .. 'z'])) or (MoumCheck(Tmp[j])) Then
Begin
Result := Res + ' ';
Exit;
End
Else
Begin
i := Pos(Copy(Tmp, j, 2), EngJongsung);
If i > 0 Then
Begin
Res := Res + Copy(Tmp, j, 2);
End
Else
Begin
Res := Res + Tmp[j] + ' ';
End;
End;
Result := Res;
end;
function DecodingEngToHan(src: Ansistring): Ansistring;
var
UniCode: integer;
ChoSung, JungSung, JongSung: integer;
ChoSungPos, JungSungPos, JongSungPos: integer;
Tmp: Ansistring;
Tmp2: Array [0 .. 2] of ansichar;
Begin
Result := '';
Tmp := DivChoJungJong(src);
If Length(Tmp) = 1 Then
Begin
ChoSungPos := Pos(Tmp + ' ', EngChosung);
JungSungPos := Pos(Tmp + ' ', EngJungsung);
JongSungPos := Pos(Tmp + ' ', EngJongsung);
If ChoSungPos > 0 Then
Result := Copy(ChoSungTbl, ChoSungPos, 2)
Else If JungSungPos > 0 Then
Result := Copy(JungSungTbl, JungSungPos, 2)
Else If JongSungPos > 0 Then
Result := Copy(JongSungTbl, JongSungPos, 2)
Else
Result := Tmp;
Exit;
End
Else If Length(Tmp) <> 6 Then
Begin
Result := Tmp;
Exit;
End;
ChoSungPos := Pos(Copy(Tmp, 1, 2), EngChosung);
JungSungPos := Pos(Copy(Tmp, 3, 2), EngJungsung);
JongSungPos := Pos(Copy(Tmp, 5, 2), EngJongsung);
//
If (ChoSungPos And JungSungPos And JongSungPos) = 0 Then
Exit;
ChoSung := (ChoSungPos - 1) Div 2;
JungSung := (JungSungPos - 1) Div 2;
JongSung := (JongSungPos - 1) Div 2;
UniCode := UniCodeHangeulBase + (ChoSung * 21 + JungSung) * 28 + JongSung;
WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, @UniCode, 1, @Tmp2, 2, nil, nil);
Result := Tmp2[0] + Tmp2[1];
end;
function CutFirstHangul(src: Ansistring): Ansistring;
var
l: integer;
Begin
l := Length(src);
If l < 2 Then
Result := src
Else If (Length(DivChoJungJong(src)) <> 6) Then
Result := src[1]
Else If (l < 3) Then
Result := src
Else If (Length(DivChoJungJong(Copy(src, 1, 2))) = 6) And (not CharKeyCheck(src[3])) Then
Result := Copy(src, 1, 2)
Else If (l < 4) Then
Result := src
Else If (Length(DivChoJungJong(Copy(src, 1, 2))) = 6) And
((not CharKeyCheck(src[3])) or (Length(DivChoJungJong(Copy(src, 3, 2))) = 6)) Then
Result := Copy(src, 1, 2)
Else If (l < 5) Then
Result := src
Else If (Length(DivChoJungJong(Copy(src, 1, 3))) = 6) And
((not CharKeyCheck(src[4])) or (Length(DivChoJungJong(Copy(src, 4, 2))) = 6)) Then
Result := Copy(src, 1, 3)
Else If (l < 6) Then
Result := src
Else If (Length(DivChoJungJong(Copy(src, 1, 4))) = 6) And
((not CharKeyCheck(src[5])) Or (Length(DivChoJungJong(Copy(src, 5, 2))) = 6)) Then
Result := Copy(src, 1, 4)
Else
Result := Copy(src, 1, 5);
end;
function ConvEngToHan(src: Ansistring): Ansistring;
var
s, r, t: Ansistring;
Begin
s := src;
r := '';
If Trim(src) <> '' Then
Begin
Repeat
t := CutFirstHangul(s);
r := r + DecodingEngToHan(t);
Delete(s, 1, Length(t));
Until s = '';
End;
Result := r;
end;
function HanDiv(const Han: PAnsiChar; Han3: PAnsiChar): boolean;
var
UniCode: Word;
ChoSung, JungSung, JongSung: integer;
begin
Result := False;
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, Han, 2, @UniCode, 1);
if (UniCode < UniCodeHangeulBase) or (UniCode > UniCodeHangeulLast) then
Exit;
UniCode := UniCode - UniCodeHangeulBase;
ChoSung := UniCode div (21 * 28);
UniCode := UniCode mod (21 * 28);
JungSung := UniCode div 28;
UniCode := UniCode mod 28;
JongSung := UniCode;
StrLCopy(Han3, PAnsiChar(ChoSungTbl) + ChoSung * 2, 2);
StrLCopy(Han3 + 2, PAnsiChar(JungSungTbl) + JungSung * 2, 2);
StrLCopy(Han3 + 4, PAnsiChar(JongSungTbl) + JongSung * 2, 2);
Result := True;
end;
function HanDivPas(const src: Ansistring; Check: integer): Ansistring;
var
Buff: array [0 .. 6] of ansichar;
B, c: Ansistring;
i: integer;
begin
B := '';
c := '';
For i := 1 To Length(src) Do
Begin
B := Copy(src, ((i - 1) * 2) + 1, 2);
if Length(Trim(B)) = 2 then
begin
if HanDiv(PAnsiChar(B), Buff) then
begin
Buff[6] := #0;
If Check = 1 Then
c := c + Copy(Ansistring(Buff), 1, 2)
Else If Check = 2 Then
c := c + Copy(Ansistring(Buff), 3, 2)
Else If Check = 3 Then
c := c + Copy(Ansistring(Buff), 5, 2);
end;
end;
End;
HanDivPas := c;
end;
Function GetHanType(const src: Ansistring): boolean;
var
Len, Hi, Lo: integer;
begin
Result := False;
if Length(src) < 2 then
Exit;
Len := Length(src);
Hi := Ord(src[Len - 1]);
Lo := Ord(src[Len]);
// if ($A1 > Lo) or ($FE < Lo) then Exit;
if ($B0 <= Hi) and ($C8 >= Hi) then
Result := True // 한글
Else if ($CA <= Hi) and ($FD >= Hi) then
Result := False // 한자
Else
Result := False; // 기타
end;
end.
|