Delphi Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
델파이 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
FreePascal/Lazarus
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
델마당
볼랜드포럼 광고 모집

델파이 Q&A
Delphi Programming Q&A
[16118] Re:한글을 분해하고 조합하는 코드인데 수정 부탁드립니다.
[] 756 읽음    2020-06-11 15:41
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.

+ -

관련 글 리스트
16110 한글을 분해하고 조합하는 코드인데 수정 부탁드립니다. 첫눈 842 2020/05/21
16118     Re:한글을 분해하고 조합하는 코드인데 수정 부탁드립니다. 756 2020/06/11
16111     Re: 길게도 짰네요. C++17 테크닉으로 구현하면 748 2020/05/25
16112         Re:Re: 길게도 짰네요. C++17 테크닉으로 구현하면 빌더(TWx) 821 2020/05/25
16113             Re:Re:Re: 길게도 짰네요. C++17 테크닉으로 구현하면 질문 996 2020/05/26
16114                 Re:Re:Re:Re: 길게도 짰네요. C++17 테크닉으로 구현하면 빌더(TWx) 1245 2020/05/26
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.