【发布时间】:2020-12-13 21:44:17
【问题描述】:
将 UTF-8 编码的表情符号转换为字符串时,我们没有使用 UTF8ToString 获得正确的字符。我们从外部接口接收这些 UTF8 字符。 我们使用在线 UTF8 解码器测试了 UTF 字符,发现它们包含正确的字符。我怀疑这些是复合字符。
procedure TestUTF8Convertion;
const
utf8Denormalized: RawByteString = #$ED#$A0#$BD#$ED#$B8#$85#$20 + #$ED#$A0#$BD#$ED#$B8#$86#$20 + #$ED#$A0#$BD#$ED#$B8#$8A;
utf8Normalized: RawByteString = #$F0#$9F#$98#$85 + #$F0#$9F#$98#$86 + #$F0#$9F#$98#$8A;
begin
Memo1.Lines.Add(UTF8ToString(utf8Denormalized));
Memo1.Lines.Add(UTF8ToString(utf8Normalized));
end;
Memo1 中的输出:
非规范化:���� ���� ����
归一化:????????????
基于WinApi函数MultiByteToWideChar编写自己的转换函数没有解决这个问题。
function UTF8DenormalizedToString(s: PAnsiChar): string;
var
pwc: PWideChar;
len: cardinal;
begin
GetMem(pwc, (Length(s) + 1) * SizeOf(WideChar));
len := MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, @s[0], -1, pwc, length(s));
SetString(result, pwc, len);
FreeMem(pwc);
end;
【问题讨论】:
-
#$ED#$A0#$BD在“非私人使用高代理”范围内,#$ED#$B8#$85在 UTF-8 中的“低代理”范围内,它本身永远不会有意义。剩下的#$20只是一个空格。见stackoverflow.com/a/51051607/4299358 -
我不明白的是:UTF-8 序列
#$ED#$A0#$BD和#$ED#$B8#$85都显示了这个字形:�。 (我尝试了以下 UTF8Decoder:mothereff.in/utf-8)而串联序列\xED\xA0\xBD\xED\xB8\x85显示预期的表情符号字形:???? -
回到我的问题:如何转换这个 UTF-8 序列
#$F0#$9F#$98#$85以便获得表情符号U+1F605? -
@SchneiderInfosystemsLtd 查看我刚刚发布的答案。
标签: delphi utf-8 delphi-10.4-sydney