webサーバから取得したデータが文字コードそのままで保存してしまう対処方法を教えてください

29 views
Skip to first unread message

清水@Anthnet

unread,
Aug 17, 2023, 12:47:34 AM8/17/23
to Japan RAD Studio User Group
清水@アンソネットです。

開発環境はdelphixe7、Indy10.6を使用しています。
webサーバから取得したデータが
文字コードそのままで保存してしまう対処方法を教えてください。
保存したファイルを再変換して読めるようにするしか方法がありませんか?
なにか良い方法があれば教えてください。

保存されたjsonファイル
{"result": {"supplier": {"companyName": [{"text": "\u30ea\u30d0 hogehoge・・

本当はこのように保存したい
{"result": {"supplier": {"companyName": [{"text": "リバ   hogehoge・・

ソース

try
RespJson := TStringlist.create;
Params := TIdMultipartFormDataStream.Create;
try
Params.AddFile('image', m_file, '');
Params.AddFormField('language', 'ja');

IdHTTP := TIdHTTP.Create(nil);
try
LHandler := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP);
LHandler.SSLOptions.Method := sslvTLSv1_2;

IdHTTP.IOHandler := LHandler;
IdHTTP.Request.CharSet := 'utf-8';

IdHTTP.Request.ContentType := 'multipart/form-data';
IdHTTP.Request.CustomHeaders.Add('api-key:hogehoge');

try

RespJson.Text := IdHTTP.Post(AUrl, Params);
if idHTTP.ResponseCode = 200 then begin

RespJson.SaveToFile(m_savefilename1);

end;
finally
// ShowMessage(idHTTP.ResponseText + sLineBreak + idHTTP.Response.WWWAuthenticate.Text);
end;
finally
IdHTTP.Free;
end;
finally
RespJson.free;
Params.Free;
end;

finally
end;

mam

unread,
Aug 17, 2023, 9:19:32 PM8/17/23
to Japan RAD Studio User Group
\uxxxx
はどうやらユニコード(21ビット)のようですね。

https://mam-mam.net/delphi/convert_utf8.html
にある
UMamUnicode.pas ユニット
を使用し、更にTRegEx.Replaceで正規表現を使って置換するのは如何でしょうか。
以下適当に作成したサンプルソースコードです。

//uses にSystem.RegularExpressions, UMamUnicode を追加する

//TRegEx.Replaceで使用する関数
function TForm1.MatchReplace(const m: TMatch): string;
var i:integer;
    s:string;
    b1,b2:TBytes;
begin
  //マッチした文字列から先頭2文字\uを削除する
  s:=m.Value.Substring(2);
  i:=StrToInt('$'+s);//数値に変換
  //ユニコード(21ビット)のバイト配列に変換
  SetLength(b1,3);
  b1[0]:=(i and $ff0000) shr 16;
  b1[1]:=(i and $ff00) shr 8;
  b1[2]:=i and $ff;
  //ユニコード(21ビット)からUTF16LEのバイト配列に変換
  b2:=MamU32ToU16(b1);
  //バイト配列から文字に変換
  result:=TEncoding.Unicode.GetString(b2);
end;

procedure TForm1.Button1Click(Sender: TObject);
var st:string;
    e:TMatchEvaluator;
begin
  //テスト用の適当な文字列
  st:='["text":"\u30ea\u30d0\u30fc\u30b9'+#13#10+' hogehoge"]';
  e:=MatchReplace;//関数を設定
  //\uから始まるUnicodeを置換する
  st:=TRegEx.Replace(st,'\\u[0-9a-f]{1,6}',e,[]);
  showmessage(st);
end;

2023年8月17日木曜日 13:47:34 UTC+9 清水@Anthnet:

mam

unread,
Aug 17, 2023, 9:40:02 PM8/17/23
to Japan RAD Studio User Group
先ほどの投稿は動作するのですが、間違っているようです。
どうやら\uxxxxは、ユニコード(21ビット)ではなく、UTF16LEのようです。
そうすると、以下で動作します。
(UMamUnicode.pas ユニットは不要です)

//uses にSystem.RegularExpressions を追加する

//TRegEx.Replaceで使用する関数
function TForm1.MatchReplace2(const m: TMatch): string;

var i:integer;
    s:string;
    b:TBytes;

begin
  //マッチした文字列から先頭2文字\uを削除する
  s:=m.Value.Substring(2);
  i:=StrToInt('$'+s);//数値に変換
  //UTF16LEのバイト配列に変換
  SetLength(b,2);
  b[1]:=(i and $ff00) shr 8;
  b[0]:=i and $ff;
  result:=TEncoding.Unicode.GetString(b);
  TEncoding.Unicode
end;

procedure TForm1.Button3Click(Sender: TObject);

var st:string;
    e:TMatchEvaluator;
begin
  //テスト用の適当な文字列
  st:='["text":"\u30ea\u30d0\u30fc\u30b9'#13#10' hogehoge"]';
  e:=MatchReplace2;//関数を設定
  //\uから始まるUnicodeを置換する
  st:=TRegEx.Replace(st,'\\u[0-9a-f]{1,4}',e,[]);
  showmessage(st);
end;






2023年8月18日金曜日 10:19:32 UTC+9 mam:

清水@Anthnet

unread,
Aug 17, 2023, 10:04:58 PM8/17/23
to Japan RAD Studio User Group
清水@アンソネットです。

ご返信ありがとうございます。
いろいろとネットで検索して解決できました。


   LJSONValue : TJSONValue;

if idHTTP.ResponseCode = 200 then begin

LJSONValue :=TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(RespJson.Text),0);
RespJson.Text :=LJSONValue.ToString;

RespJson.SaveToFile(m_savefilename1,TEncoding.UTF8);

end;

2023年8月18日金曜日 10:40:02 UTC+9 mam:
Reply all
Reply to author
Forward
0 new messages