将特殊字符(例如 Ñ 和 Ò)转换回其在 C# 中的原始拉丁字母对应项

问题描述 投票:0回答:6

我从 MySQL 数据库中得到了一个导出,随着时间的推移,该数据库的编码似乎有些混乱,并且包含

HTML char codes
(例如
& uuml;
)和表示相同字母(例如
ü
)的更多有问题的字符的混合Ã
。我的任务是使文件恢复一定的一致性并将所有内容都转换为正确的拉丁字符,例如
ú
ó

我正在处理的字符串类型的一个例子是

Flåchen 的消毒剂

这应该等于

50 Tattoo Desinfektionsl ö    sungst ü    cher f ü    r Fl ä    chen 
50 Tattoo Desinfektionsl ö sungst ü cher f ü r Fl ä chen

C#/.Net 4.5 中是否有一种方法可以成功地将

ü
Ã
重新编码为
UTF-8

否则建议采取什么方法?

上面示例字符串中的段落字符

是实际的段落字符还是其他字符组合的一部分?

我在需要查找和替换的情况下创建了一个查找表,如下所示,但我不确定它有多完整。

É -> É
“ -> "
†-> "
Ç -> Ç
à -> Ã
é, 'é
à -> ú -> ú
• -> -
Ø -> Ø
õ -> õ
í -> í
â -> â
ã -> ã
ê -> ê
á -> á
é -> é
ó -> ó
– -> –
ç -> ç
ª -> ª
º -> º
à  -> à
c# character-encoding special-characters latin mojibake
6个回答
29
投票

首先,由于数据是使用错误的编码进行解码的,因此某些字符可能无法恢复。看起来像是使用 8 位编码错误解码的 UTF-8 数据。

没有内置方法可以恢复这样的数据,因为这不是您通常会做的事情。没有可靠的方法来解码数据,因为它已经损坏了。

您可以尝试的是对数据进行编码,然后再次使用错误的编码对其进行解码,反之亦然:

byte[] data = Encoding.Default.GetBytes(input);
string output = Encoding.UTF8.GetString(data);

Encoding.Default
使用系统当前的 ANSI 编码。您可以在那里尝试一些不同的编码,看看哪一种可以提供最佳结果。


17
投票

由于 Windows-1252 编码有 5 个未分配的插槽,数据仅部分不可恢复。 Windows-1252 的一些修改填充了这些控制 字符,但这些字符不会出现在 Stackoverflow 中的帖子中。如果修改 Windows-1252已经用过只要不丢失就可以完全恢复 复制粘贴中隐藏的控制字符。

还有不间断空格字符,通常会在复制粘贴时被忽略或变成空格,但当您直接处理字节时,这不是问题。

该字符串所经历的错误编码滥用是:

UTF-8 -> Windows-1252 -> UTF-8 -> Windows-1252

要恢复,这里有一个示例:

String a = "Desinfektionslösungstücher für Flächen";
Encoding utf8 = Encoding.GetEncoding(65001);
Encoding win1252 = Encoding.GetEncoding(1252);

string result = utf8.GetString(win1252.GetBytes(utf8.GetString(win1252.GetBytes(a))));

Console.WriteLine(result);
//Desinfektionslösungstücher für Flächen

4
投票

它可能是 windows-1252 编码的字符串,您将其读取为 UTF-8。

正如 Guffa 提到的,数据已损坏。

让我们看一下字节:
ö -> UTF8 中的 C3B6

在 windows-1252 中 C3 ->à B6 ->¶

所以 ö ->

所有这些“f”怎么样:

->83 ->C2

老实说,我不知道它们为什么会出现,但你可以尝试删除它们并按照 Guffa 提到的那样进行一些转换。祝你好运


1
投票

在这里您可以找到完整的列表:

http://bueltge.de/wp-content/download/wk/utf-8_kodierungen.pdf


0
投票

我之前也被这个char问题困扰过。 解决方案:

我的 .(cs)html 文件是 UTF-8;我转换为 UTF-8Y(带 BOM 的 UTF-8)。


0
投票

这确实是双重编码的失败,所以你必须像这样从 UTF_8 到 ISO_8859_1 双重解码(转换):

writeln(CharsetConversion(CharsetConversion('Desinfektionslösungstücher für Flächen', UTF_8,ISO_8859_1),UTF_8,ISO_8859_1));

© www.soinside.com 2019 - 2024. All rights reserved.