Windows-1252到UTF-8编码

Sam*_*Sam 33 encoding utf-8 character-encoding windows-1252

我已经将某些文件从Windows机器复制到了Linux机器上.因此,所有Windows编码(windows-1252)文件都需要转换为UTF-8.不应更改已存在UTF-8的文件.我打算使用该recode实用程序.如何指定该recode实用程序应仅转换windows-1252编码的文件而不是UTF-8文件?

重新编码的示例用法:

recode windows-1252.. myfile.txt
Run Code Online (Sandbox Code Playgroud)

myfile.txt将从windows-1252 转换为UTF-8.在此之前,我想知道myfile.txt实际上是windows-1252编码而不是UTF-8编码.否则,我相信这会破坏文件.

Gre*_*osz 66

你可以使用iconv:

iconv -f WINDOWS-1252 -t UTF-8 filename.txt

  • 它看起来像的iconv输出到标准输出,所以你可能会想它重定向,如`...>文件名,utf8.txt` (5认同)
  • 请注意,如果文件已经是 UTF8,这将很高兴地对其进行双重编码,从而使您无法阅读。 (2认同)

Jon*_*eet 36

您如何期望重新编码知道文件是Windows-1252?理论上,我相信任何文件都是有效的Windows-1252文件,因为它将每个可能的字节映射到一个字符.

现在肯定有一些强烈暗示它是UTF-8的特性 - 例如,如果它以UTF-8 BOM开头 - 但它们不是确定的.

一种选择是首先检测它是否真的是一个完全有效的UTF-8文件,我想......再次,这只是暗示性的.

我不熟悉recode工具本身,但你可能想知道它是否能够从同一个编码重新编码文件- 如果你使用无效文件(即包含无效的UTF-8字节序列的文件)它可能很好地将无效序列转换成问号或类似的东西.此时,您可以通过将文件重新编码为UTF-8并查看输入和输出是否相同来检测文件是否为有效UTF-8.

或者,以编程方式执行此操作而不是使用重新编码实用程序 - 例如,它在C#中非常简单.

但重申一下:所有这些都是启发式的.如果你真的不知道文件的编码,那么没有任何东西可以100%准确地告诉你它.

  • cp1252没有映射到字符的几个字节:0x81,0x8D,0x8F,0x90,0x9D.然而,重点是.我不会尝试批量转换来自多个不同来源的文件编码. (11认同)
  • ISO-8859-1将每个字节映射到一个字符,其中"80..9F"范围是C1控制字符.在Java中,我可以使用ISO-8859-1将"00..FF"范围内的每个字节解码为一个字符串,然后对其进行重新编码以获取原始字节.当我尝试使用windows-1252时,我会为列出的bobince值获取垃圾.这令我感到惊讶; 我认为它会用ISO-8859-1中相应的控制字符填补这些空白. (4认同)
  • 我知道它们不一样,但cp1252通常被描述为与Latin-1相同,但大多数无用的控制字符都被有用的打印字符所取代.如果微软真的开始使用Latin-1并按照描述的意思进行调整,我希望剩下的字节映射到那些相同的控制字符.但事实证明,这两种编码几乎是并排(有点),而我的假设是我和Umption的屁股.: - / (3认同)
  • @AlanMoore:为什么你会期望它使用不同编码的字符来填补空白?Windows-1252和ISO-8859-1不是一回事,但人们(显然也是你)认为它们是可能的. (2认同)
  • @JCoombs:如果您不知道编码,最好不要将其视为文本. (2认同)
  • @JCoombs:Cp1252是ISO 8859-1的超集,但不是ISO-8859-1的超集.是的,不管你信不信,额外的冲刺有所不同.ISO-8859-1用U + 0080到U + 009F填充字节0x80到0x9f,所有这些都是控制字符IIRC. (2认同)

Seb*_*oli 9

这是我对类似问题的另一个答案的转录:

如果将utf8_encode()应用于已经是UTF8的字符串,它将返回乱码的UTF8输出.

我做了一个解决所有这些问题的功能.它叫做Encoding :: toUTF8().

您不需要知道字符串的编码是什么.它可以是Latin1(iso 8859-1),Windows-1252或UTF8,或者字符串可以混合使用它们.Encoding :: toUTF8()会将所有内容转换为UTF8.

我这样做是因为一项服务给了我一个混乱的数据,将UTF8和Latin1混合在同一个字符串中.

用法:

$utf8_string = Encoding::toUTF8($utf8_or_latin1_or_mixed_string);

$latin1_string = Encoding::toLatin1($utf8_or_latin1_or_mixed_string);
Run Code Online (Sandbox Code Playgroud)

下载:

https://github.com/neitanod/forceutf8

更新:

我已经包含了另一个函数Encoding :: fixUFT8(),它将修复每个看起来乱码的UTF8字符串.

用法:

$utf8_string = Encoding::fixUTF8($garbled_utf8_string);
Run Code Online (Sandbox Code Playgroud)

例子:

echo Encoding::fixUTF8("Fédération Camerounaise de Football");
echo Encoding::fixUTF8("Fédération Camerounaise de Football");
echo Encoding::fixUTF8("FÃÂédÃÂération Camerounaise de Football");
echo Encoding::fixUTF8("Fédération Camerounaise de Football");
Run Code Online (Sandbox Code Playgroud)

将输出:

Fédération Camerounaise de Football
Fédération Camerounaise de Football
Fédération Camerounaise de Football
Fédération Camerounaise de Football
Run Code Online (Sandbox Code Playgroud)

更新:我已经将函数(forceUTF8)转换为一个名为Encoding的类的静态函数族.新函数是Encoding :: toUTF8().


小智 8

没有通用的方法来判断文件是否使用特定编码进行编码.请记住,编码只不过是一个"协议",文件中的位应该如何映射到字符.

如果您不知道哪些文件实际上已经用UTF-8编码,哪些文件在windows-1252中编码,则必须检查所有文件并自行查找.在最糟糕的情况下,这可能意味着您必须使用两种编码中的任何一种打开它们中的每一种,并查看它们是否"看起来"正确 - 即,所有字符都正确显示.当然,您可以使用工具支持来执行此操作,例如,如果您确定某些字符包含在windows-1252与UTF-8中具有不同映射的文件中,您可以为它们进行grep通过Seva Akekseyev提到的'iconv'运行文件后.

如果您知道文件实际上只包含在UTF-8和Windows-1252中编码相同的字符,那么您的另一个幸运案例就是.在那种情况下,当然,你已经完成了.

  • Linux utils:`file`并不总是猜测正确的编码. (3认同)

Ant*_* O. 6

如果要在单个命令中重命名多个文件 - 假设您要转换所有*.txt文件 - 这是命令:

find . -name "*.txt" -exec iconv -f WINDOWS-1252 -t UTF-8 {} -o {}.ren \; -a -exec mv {}.ren {} \;
Run Code Online (Sandbox Code Playgroud)

  • 这会将 **所有文件转换为 UTF-8** 而不考虑其编码,并且会弄乱已经采用 UTF-8 格式的文件,并且**不是** OP 想要的 (2认同)