我尝试将utf8中的文本转换为windows1251。
这是源文本Ñàíêò-Ïåòåðáóðã 这是目标Санкт-Петербург
我测试了很多功能:Utf8ToAnsi,UTF8ToString,Utf8Encode等但是没有得到真正的结果。
需要帮助。
答案 0 :(得分:6)
让我们试着猜猜你在问什么。看看前五个字符:
Ñàíêò
如果我们假设它们实际上来自8 bit Windows code page 1252,那么在十六进制中它们就像这样编码:
D1 E0 ED EA F2
现在,解释为8 bit Windows code page 1251时的那五个字节是:
Санкт
所以似乎这里没有涉及UTF-8。您只是将文本误解为来自代码页1252,而实际上它来自1251。
我测试了很多功能:Utf8ToAnsi,UTF8ToString,Utf8Encode等,但没有得到真实的结果。
更一般地说,当你发现自己随意调用函数时,通常这意味着你还没有完全理解这个问题。能够识别这种感觉是一种有用的技能,并且知道是时候退后一步并尝试获得更深入的理解。
对于解释如何从UTF-8转换为1251的人来说,没有太多意义,因为那不是你需要做的。我不会试图向您展示任何解决问题的代码,因为我不知道:
很可能你已经将这些字节读入AnsiString
代码页1252.但是在这一点上,我判断猜测是一个太过分的步骤。如果您在问题中添加一些说明,那么我们可以添加更多详细信息。
答案 1 :(得分:0)
我尝试将utf8中的文本转换为windows1251。
由于您使用的是Delphi 2009+,最简单的解决方案是使用UT8String
和AnsiString(N)
类型,让RTL为您处理转换(除非您正在为移动平台进行编译,其中如果没有安装third party compiler patch),则无法使用案例UTF8String
和AnsiString(N)
:
type
Win1251String = type AnsiString(1251);
var
Utf8: UTF8String;
Win1251: Win1251String;
begin
// populate UTF-8 as needed...
Utf8 := ...;
// converts from UTF-8 to UTF-16 to Windows-1251...
Win1251 := Win1251String(Utf8);
// use Win1251 as needed...
end;
或者,您可以使用RTL的UnicodeFromLocaleChars()
和LocaleCharsFromUnicode()
函数:
var
Utf8: UTF8String;
Utf16: UnicodeString;
Win1251: RawByteString;
begin
// populate UTF-8 as needed...
Utf8 := ...;
// convert from UTF-8 to UTF-16...
SetLength(Utf16, UnicodeFromLocaleChars(65001, 0, PAnsiChar(UTf8), Length(Utf8), nil, 0));
UnicodeFromLocaleChars(65001, 0, PAnsiChar(Utf8), Length(Utf8), PWideChar(Utf16), Length(Utf16));
// convert from UTF-16 to Windows-1251...
SetLength(Win1251, LocaleCharsFromUnicode(1251, 0, PWideChar(Utf16), Length(Utf16), nil, 0, nil, nil));
LocaleCharsFromUnicode(1251, 0, PWideChar(Utf16), Length(Utf16), PAnsiChar(Win1251), Length(Win1251), nil, nil);
SetCodePage(Win1251, 1251);
// use Win1251 as needed...
end;
或者您可以直接使用Win32 MultiByteToWideChar()
和WideCharToMultiByte()
函数(或第三方Unicode库,例如iconv或ICU):
var
Utf8: UTF8String;
Utf16: UnicodeString; // or WideString in pre-2009 versions
Win1251: AnsiString;
begin
// populate UTF-8 as needed...
Utf8 := ...;
// convert from UTF-8 to UTF-16...
SetLength(Utf16, MultiByteToWideChar(65001, 0, PAnsiChar(UTf8), Length(Utf8), nil, 0));
MultiByteToWideChar(65001, 0, PAnsiChar(Utf8), Length(Utf8), PWideChar(Utf16), Length(Utf16));
// convert from UTF-16 to Windows-1251...
SetLength(Win1251, WideCharToMultiByte(1251, 0, PWideChar(Utf16), Length(Utf16), nil, 0, nil, nil));
WideCharToMultiByte(1251, 0, PWideChar(Utf16), Length(Utf16), PAnsiChar(Win1251), Length(Win1251), nil, nil);
// use Win1251 as needed...
end;
这是源文本Ñàíêò-Ïåòåðáóðã这是目标Санкт-Петербург
Ñàíêò-Ïåòåðáóðã
不是Санкт-Петербург
的UTF-8编码形式,正确的UTF-8编码形式将是Санкт-Петербург
。因此,正如其他人所指出的那样,您的数据实际上并不是以UTF-8开头编码的。
我测试了很多功能:Utf8ToAnsi,UTF8ToString,Utf8Encode等但是没有得到真正的结果。
Utf8ToAnsi()
不允许您指定目标字符集。在Delphi 2009+中,它将UTF-8字符串解码为UTF-16 UnicodeString
。在2009年之前的版本中,它解码为AnsiString
,使用操作系统默认的Ansi代码页进行编码,无论发生什么情况。
UTF8ToString()
将UTF-8字符串解码为UTF-16 UnicodeString
。
Utf8Encode()
将UTF-16 WideString
/ UnicodeString
编码为UTF-8。