2021/09/13

解析 Delphi 7 挑戰:從 WideString 到 UTF16 的轉換技術!

 

作者:吳祐賓

 


 

 

底下的程式內容到了 XE 後已經被 TEncoding 物件所取代,但這問題時常被問到,之前主流是 Base64,當時還可以用 EncdDecd 單元處理 Unicdoe 編碼,現在已逐漸改以 JSON 格式為主流,EncdDecd 單元已無法滿足眼下的需求了。

 

WideString 是 Delphi 7 相容 Unicode 的字串類型,然而 WideString 的存在是為了當時的 Win32 API 而存在的,它並不適合作為現代化的資料傳輸格式。

 

要達到良好的相容性,使用 UTF16 是比較好的選擇。可以確定的是 Delphi 7 沒有 WideString 對 JSON 的 Encode 和 Decode 的函式內容。不想自己寫?不囉嗦,直接為您獻上程式碼:

 

 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
function DecodeUTF16(sStr: string): WideString;
var
  i: Integer;
  StrPos: Integer;
  temp, top, last: string;
  ResultStr: WideString;
begin
  ResultStr := '';
  repeat
    StrPos := Pos('\u', sStr) - 1;
    if StrPos < 0 then begin            // 無 unicode 編碼不需轉換
      last := sStr;
      ResultStr := ResultStr + last;
      Break;
    end;
    top := Copy(sStr, 1, StrPos);       // 取出編碼字符前非 unicode 編碼的文字,如數字
    temp := Copy(sStr, StrPos + 1, 6);  // 取出編碼,包括 \u,如\u53f0
    Delete(temp, 1, 2);
    Delete(sStr, 1, StrPos + 6);
    ResultStr := ResultStr + top + WideChar(StrToInt('$' + temp));
  until (StrPos >= 0);
  Result := ResultStr;
end;

function EdenUTF16(const sStr: WideString): string;
var
  w: Word;
  StrPos: Integer;
  UTF16Str, TmpStr: string;
begin
  TmpStr := '';
  for StrPos:=1 to Length(sStr) do begin
    w := Ord(sStr[StrPos]);
    UTF16Str := IntToHex(w, 4);
    TmpStr := TmpStr +'\u'+ UTF16Str;
  end;
  Result := TmpStr;
end;

 

 

結論時間

 

以上的程式碼雖然能應用在實戰中,其 Delphi 7 裡的函式庫幾乎沒有對 WideString 處理的問題需要正視,在尋求古老三方元件的協助也無可避免需要手刻不足的區塊;自 Delphi XE 開始至現在的 Delphi 11 早已解決絕大部份 Unicode 的麻煩。

 

若你仍有中文處理需求,真心邀請你使用 Delphi CE 社群版來進行專案提升,省下你開發的時間,專注地在商業邏輯的開發會為你帶來更好的效益,畢竟公司開來目的是為了賺錢,而非程式碼研究,研究的事我來就行。😁

 

 

和你分享 😉

 

 

Delphi in Depth DataSnap 網站應用程式全端開發 出版

 

 

沒有留言:

張貼留言