如何纠正文件的字符编码?

62

我有一个 ANSI 编码的文本文件,但其中包含了 ANSI 不支持的重音字符,因此不应该被编码为 ANSI。我宁愿使用 UTF-8。

数据是否能够正确解码,或者在转码中丢失了?

我可以使用哪些工具?

以下是我的一些样本:

ç é

从上下文可以看出(café应该是café),这两个字符应该是这两个:

ç é

2
你知道文件的原始编码吗(假设它曾经从一个字符集转换到另一个字符集)?如果是这样,您应该能够使用像这个这样的表格将结果字符映射回原始字符。如果您不知道原始编码,您可以使用基于您正在使用的语言中不同单词的频率的概率方法来解决问题。但是您可能不愿意付出需要的工作。 - gregory
很遗憾,我不知道原始编码。当客户使用各种系统创建文件时,这是一个常见问题。他们可能不知道字符编码是什么。请注意,越来越多的采用UTF-8作为默认编码的Linux桌面系统可以透明地减少此问题。 - Liam
我完全同意。UTF-8绝对是在大多数情况下使用最合理的编码,但不幸的是,你几乎不能期望客户能够理解或采取行动。 - gregory
我已经在这里相似的问题上写了相当广泛的内容。链接 - Henke
12个回答

34

使用Notepad++按以下步骤操作:

1- 复制原始文本

2- 在Notepad++中打开新文件,更改编码->选择你认为原始文本所遵循的编码。有时Unicode文件会被某些程序读取为ANSI,因此也可以尝试使用ANSI编码

3- 粘贴

4- 然后通过相同的菜单进行转换为Unicode:编码->"使用UTF-8编码"(不是“转换为UTF-8”),希望这样就可以阅读了

以上步骤适用于大多数语言。您只需要在粘贴到notepad++之前猜测原始编码,然后通过相同的菜单将其转换为另一种基于Unicode的编码,以查看是否变得可读。

大多数语言存在两种编码形式:1-旧的遗留ANSI(ASCII)形式,仅有8位,最初由大多数计算机使用。8位仅允许256种可能性,其中128种是常规的拉丁和控制字符,最后128位根据PC语言设置而被不同地读取。 2-新的Unicode标准(高达32位)为所有当前已知的语言中的每个字符提供唯一代码,并提供更多的可能性。如果一个文件是Unicode,那么只要安装了语言的字体,就应该可以在任何PC上理解它。请注意,即使UTF-8高达32位,并且与UTF-16和UTF-32一样广泛,但它尝试保持8位与拉丁字符一起使用,只是为了节省磁盘空间。


3
谢谢兄弟,你的回答让我从处理.sql文件编码问题的两天烦恼中解脱了出来。它起作用了。Mac上的Sublime Text太糟糕了! - WhySoSerious
你是个天才。 - Nir
我必须使用粘贴特殊功能 - “粘贴二进制数据”。 - fingerman
在Notepad++中,如果您只是打开原始文件,请转到编码菜单并查看所选内容。它还有一个转换功能,因此您可以查看是否匹配字符集。我知道这是一个老问题。 - DoomVroom
我已经下载了Notepad++ v8.4.2,但是没有“以UTF-8编码”菜单!有人能告诉我发生了什么吗? - starriet

22

编辑:在进入更复杂的解决方案之前,有一个简单的可能性可以消除:您是否尝试在阅读文件的文本编辑器中将字符集设置为utf8?这可能只是某人向您发送了一个utf8文件,而您正在使用设置为cp1252的编辑器进行阅读。

仅以这两个示例为例,这是utf8通过单字节编码镜头读取的情况,很可能是iso-8859-1、iso-8859-15或cp1252之一。如果您可以发布其他问题字符的示例,应该可以进一步缩小范围。

由于字符的视觉检查可能会误导,因此您还需要查看底层字节:您在屏幕上看到的§可能是0xa7或0xc2a7,这将确定您必须执行的字符集转换类型。

你能够假设所有的数据都被以完全相同的方式扭曲 - 它们来自同一来源并经历了相同的转换序列,因此例如在你的文本中没有单个é,而永远是ç吗? 如果是这样,那么可以通过一系列字符集转换来解决该问题。如果您可以更具体地说明您所处的环境和使用的数据库,这里的某个人可能会告诉您如何执行适当的转换。

否则,如果问题字符仅出现在数据的某些地方,则必须针对每种情况进行处理,基于“没有作者打算在其文本中放置ç,因此每当您看到它时,请用ç替换”等假设。后者选项更加危险,首先因为关于作者意图的这些假设可能是错误的,其次,因为您将不得不自己找出每个问题字符,如果要视觉检查的文本过多或以您不熟悉的语言或书写系统编写,则可能无法完成。


根据您所处的位置,有很多选择:使用hd -c文件名,在vi中打开并查看“奇怪”的字符转义,使用php中的bin2hex函数,或在mysql中使用hex(fieldname)函数。 - user8599
3
谢谢,这似乎是最好的解决方案。理解底层字节并智能地替换它们似乎是最明智的选择,我将开发一个脚本,以便在进行更改时自动化处理。 - Liam

11

使用命令行中的vim:

vim -c "set encoding=utf8" -c "set fileencoding=utf8" -c "wq" filename

10
当您看到像ç和é这样的字符序列时,通常表示一个UTF-8文件已被以ANSI(或类似)格式读取的程序打开。诸如以下Unicode字符:
U+00C2带抑扬符号的拉丁大写字母A U+00C3带波浪线的拉丁大写字母A U+0082允许断字处 U+0083不要在此处断字
由于UTF-8使用可变字节策略,所以这些字符往往会出现在ANSI文本中。该策略在这里有很好的解释。
对您来说,优点是这些奇怪字符的出现使得查找并替换不正确的转换实例相对容易。
我认为,由于ANSI始终使用每个字符1个字节,因此您可以通过简单的搜索和替换操作来处理此情况。或者更方便地,使用包括将有问题的序列与所需字符进行映射的表格的程序,例如:
“ -> “ # 应该是开头的双引号 â€? -> ” # 应该是结束的双引号
任何给定的文本,假设它是英文的,都将有相对较少数量的不同类型的替换。
希望这能帮到您。

4

一个简单的转换会假设数据是正确的并保留错误的数据吗? - Liam
是的,会的。我认为人们误解了问题。问题在于数据已经损坏,因此需要一个补救方案。 - gregory

2
在Sublime文本编辑器中,选择文件 -> 使用编码重新打开 -> 选择正确的编码。通常情况下,编码会被自动检测到,但如果没有,您可以使用上述方法。

1

我发现了一种简单的自动检测文件编码的方法 - 将文件更改为文本文件(在 Mac 上将文件扩展名更改为 .txt),然后将其拖到 Mozilla Firefox 窗口中(或者选择“文件”->“打开”)。Firefox 将检测编码 - 您可以在“查看”->“字符编码”下看到它检测出来的编码。

一旦知道正确的编码,我使用 TextMate 更改了文件的编码。选择“文件”->“重新使用编码”并选择您的编码,然后选择“文件”->“另存为”,将编码更改为 UTF-8 并将行尾更改为 LF(或任何您想要的格式)。


1

当我在寻找解决中文字符编码问题的方案时,我发现了这个问题,但最终我的问题只是Windows在UI中无法正确显示它们。

如果其他人也遇到同样的问题,您可以通过将Windows本地更改为中国,然后再改回来来简单解决它。

我在这里找到了解决方案:

http://answers.microsoft.com/en-us/windows/forum/windows_7-desktop/how-can-i-get-chinesejapanese-characters-to/fdb1f1da-b868-40d1-a4a4-7acadff4aafa?page=2&auth=1

我也赞同Gabriel的回答,因为在notepad++中查看数据让我意识到了问题出在Windows上。


1
如果您在文件中看到问号,或者重音已经丢失,那么返回utf8将无济于事。例如,如果café变成了cafe-仅更改编码是不会有帮助的(您需要原始数据)。
您能否在此处粘贴一些文本,这将有助于我们确切地回答。

0
在OS X上,Synalyze It!允许您以不同的编码方式显示文件的部分(所有这些编码方式都受ICU库支持)。一旦您知道源编码是什么,您可以通过剪贴板复制整个文件(字节)并插入到选择目标编码(UTF-8或其他您喜欢的编码)的新文档中。
当使用UTF-8或其他Unicode表示时,UnicodeChecker非常有帮助。

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