在C#中将特殊字符(如ü和Ã)转换回它们的原始拉丁字母对应项

23

我收到了一个来自MySQL数据库的导出文件,由于编码混乱,其中包含了一些 HTML字符编码 ,例如 ü 以及更为问题严重的字符,如 üÃ表示相同字母。我的任务是将文件恢复一致,并将所有内容转换为正确的拉丁字符,例如 úó

我正在处理的字符串示例是:

Desinfektionslösungstücher für 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

否则,哪种方法是可取的?

另外,上面例子中的段落字符是实际的段落字符还是其他字符组合的一部分?

我已经创建了一个查找替换表,在需要进行查找和替换时使用,下面是该表,但我不确定它有多完整。

É -> É
“ -> "
†-> "
Ç -> Ç
à -> Ã
é, 'é
à -> ú -> ú
• -> -
Ø -> Ø
õ -> õ
í -> í
â -> â
ã -> ã
ê -> ê
á -> á
é -> é
ó -> ó
– -> –
ç -> ç
ª -> ª
º -> º
à  -> à

13
注重细节的要点:üà 并不完全是“特殊字符”,而是**乱码**。 - Boann
@Boann离开了...有趣。 - Gga
顺便说一下,你的帖子有些误导性,修复数据后我得到了“Desinfektionslösungstücher für Flächen”,这似乎是正确的,但在你的期望结果中有空格。 - Esailija
@Esailija 是的,把空格放进去,只是为了说明映射关系... - Gga
有用的信息:为了快速调试这种问题,您可以使用此网站:https://2cyr.com/decode/?lang=en 对于这个特定的例子,请复制/粘贴问题中的字符串,然后选择UTF-8作为源,WINDOWS-1252作为显示。然后点击确定。再次将结果文本复制/粘贴到上方的文本框中,并使用相同的设置重新运行。您将看到原始字符串。 - Ahmet
有人知道这个表是否完整吗?我认为有些字符丢失了。 - George Chalhoub
5个回答

30

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

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

您可以尝试的是对数据进行编码,然后再次使用错误的编码进行解码,仅仅是相反的过程:

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

Encoding.Default使用当前系统的ANSI编码。您可以尝试一些不同的编码并查看哪个提供最佳结果。


谢谢,我认为您的理论是数据可能无法恢复的。我已经将字符串分解如下... 50 纹身消毒溶液湿巾用于表面 --- 和 ---50 纹身消毒溶液湿巾用于表面。所以我知道应该出现在哪里,但仍然无法转换。 - Gga
1
你的代码结合 @pawlakppp 的发现解决了问题,所以感谢你们两个。 - Gga
1
可能的Python 3等效写法:s.encode('raw_unicode_escape').decode('utf8') - matanster

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

谢谢,我会尝试那种方法。 - Gga
+1 这是好东西。谢谢。我已经能够使用iconv或applescript应用这个技巧了。 - Mockman

5

这可能是以windows-1252编码的字符串,但你读成了UTF-8。

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

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

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

所以ö ->ö

那么所有这些“ƒÂ”是什么意思:

ƒ ->83 Â ->C2

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


谢谢,我正在进行相同的调查,并已删除“ƒÂ”。重新导出数据已将它们删除并将A帽子转换为A波浪符号,这很好,然后似乎有一个清晰的转换,如此列在这里:http://www.i18nqa.com/debug/utf8-debug.html - Gga

2

1
我之前也遇到过这个字符问题。 解决方案: 我的 .(cs)html 文件是 UTF-8 编码的;我将其转换为带有 BOM 的 UTF-8Y 编码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接