我有一个XML文件,似乎包含双重编码的UTF-8字符。例如,然后十六进制转储中的“Gesch .... ft”部分应该是Geschäft:
00009f0: 4365 6c6c 3e3c 4861 7368 4365 6c6c 3e3c Cell><HashCell><
0000a00: 5374 7220 7661 6c75 653d 2253 746f 7265 Str value="Store
0000a10: 735f 4d65 6e75 222f 3e3c 5374 7220 7661 s_Menu"/><Str va
0000a20: 6c75 653d 2247 6573 6368 c383 c2a4 6674 lue="Gesch....ft
0000a30: 6522 2f3e 3c2f 4861 7368 4365 6c6c 3e3c e"/></HashCell><
0000a40: 4861 7368 4365 6c6c 3e3c 5374 7220 7661 HashCell><Str va
我找到了很多方法来修复UTF-8双编码数据库,文件名或数据流。但是我没有找到修复纯文本或XML文件的任何内容。
答案 0 :(得分:0)
我想出了一种在UNIX™上实现它的方法。 Z-Shell脚本中的以下四行将是它:
#!/bin/zsh
setopt No_Err_Exit
iconv -f "UTF-8" -t "ISO-8859-1" "${1}" >"${1}.new"
mv "${1}" "${1}.old"
mv "${1}.new" "${1}"
答案 1 :(得分:0)
假设双重编码只会产生2字节的utf8序列(你可以添加一个检查),快速&amp;脏:
#include <stdio.h>
int main (void)
{
int state,ch;
unsigned val;
for(state = 0; ; ) {
ch = getc(stdin);
if (ch==EOF) break;
switch(state) {
case 0:
if ((ch & 0xe0) == 0xc0) {
val = (ch & 0x1f) << 6;
state = 1;
}
else putc( ch, stdout);
break;
case 1:
val |= (ch & 0x3f);
putc(val, stdout);
state = 0;
break;
}
}
return 0;
}
这具有额外的优点,即不检查结果字节是否是有效的代码点(不需要) 结果:
$ ./a.out < gesel.in > gesel.out
$ hexdump -C gesel.in
00000000 47 65 73 65 6c c3 83 c2 a4 66 74 65 0a |Gesel....fte.|
0000000d
$ hexdump -C gesel.out
00000000 47 65 73 65 6c c3 a4 66 74 65 0a |Gesel..fte.|
0000000b
答案 2 :(得分:0)
它不是双重UTF-8编码 - 它是一个UTF-8文件,已被解码为ISO-8859-1,然后以UTF-8编码保存。阿卡。变为乱码。
要在Python中解决此问题:
import io
with io.open('mojibake.xml', 'r+', encoding='utf-8') as mojibaked_input_file:
input_baked = mojibaked_input_file.read()
# Reverse the wrong interpretation
input_fixed = input_baked.encode('latin1').decode('utf-8')
mojibaked_input_file.seek(0)
mojibaked_input_file.truncate()
mojibaked_input_file.write(input_fixed)
答案 3 :(得分:0)
要删除双重编码,您需要将文件从UTF-8转换为第二次转换为utf8时被错误地用作源字符集的字符集。
对于德语和其他西欧语言,最好的选择是使用“ Windows-1252”或“ CP1252”。它与Latin-1相同,不同之处在于它还有更多字符,并且在尝试转换为Latin-1时会产生错误。
有几种工具可用于删除双重编码。在Mac和Linux上,默认情况下安装了iconv
,因此您可以尝试
iconv -f utf8 -t cp1252 $YourFile > $NewFile
但是,如果您的文件也以BOM表(Byte order mark)开头,则可能会出现以下错误:
iconv: illegal input sequence at position 0
在这种情况下,请改用uconv
,它使用相同的参数,但确实在文件开头处处理BOM:
uconv -f utf8 -t cp1252 $YourFile > $NewFile
在基于Debian的Linux发行版中,它随附
apt install icu-devtools
在Mac上,可以使用brew
安装它:
brew install icu4c