我如何测试文本文件的编码…有效吗?它是什么?


46

我有几个.htmGedit中打开的文件,没有任何警告/错误,但是当我在中打开这些文件时Jedit,它警告我无效的UTF-8编码...

HTML元标记表示“ charset = ISO-8859-1”。Jedit允许使用一个后备编码列表和一个编码自动检测器列表(当前为“ BOM XML-PI”),因此我的直接问题已经解决。但是,这让我开始思考:如果不存在元数据怎么办?

当编码信息不可用时,是否有一个CLI程序可以“猜测”哪些编码可能适用?

而且,尽管这是一个稍微不同的问题;是否有一个CLI程序来测试已知编码的有效性?


类似于“如何自动检测文本文件编码?” superuser.com/questions/301552/...
buzz3791

Answers:


60

file命令使有关编码的“最佳猜测”。使用-i参数强制file打印有关编码的信息。

示范:

$ file -i *
umlaut-iso88591.txt: text/plain; charset=iso-8859-1
umlaut-utf16.txt:    text/plain; charset=utf-16le
umlaut-utf8.txt:     text/plain; charset=utf-8

这是我创建文件的方式:

$ echo ä > umlaut-utf8.txt 

如今,一切都是utf-8。但是说服自己:

$ hexdump -C umlaut-utf8.txt 
00000000  c3 a4 0a                                          |...|
00000003

https://en.wikipedia.org/wiki/Ä#Computer_encoding比较

转换为其他编码:

$ iconv -f utf8 -t iso88591 umlaut-utf8.txt > umlaut-iso88591.txt 
$ iconv -f utf8 -t utf16 umlaut-utf8.txt > umlaut-utf16.txt 

检查十六进制转储:

$ hexdump -C umlaut-iso88591.txt 
00000000  e4 0a                                             |..|
00000002
$ hexdump -C umlaut-utf16.txt 
00000000  ff fe e4 00 0a 00                                 |......|
00000006

通过混合所有三个来创建“无效”的东西:

$ cat umlaut-iso88591.txt umlaut-utf8.txt umlaut-utf16.txt > umlaut-mixed.txt 

怎么file说:

$ file -i *
umlaut-iso88591.txt: text/plain; charset=iso-8859-1
umlaut-mixed.txt:    application/octet-stream; charset=binary
umlaut-utf16.txt:    text/plain; charset=utf-16le
umlaut-utf8.txt:     text/plain; charset=utf-8

没有-i

$ file *
umlaut-iso88591.txt: ISO-8859 text
umlaut-mixed.txt:    data
umlaut-utf16.txt:    Little-endian UTF-16 Unicode text, with no line terminators
umlaut-utf8.txt:     UTF-8 Unicode text

file命令不知道“有效”或“无效”。它只是看到一些字节并试图猜测可能是什么编码。作为人类,我们也许可以识别出文件是带有“错误”编码的变音符号的文本文件。但是,作为计算机,它需要某种人工智能。

有人可能会说,启发式file是某种人工智能。但是,即使是这样,它也是非常有限的。

这是有关file命令的更多信息:http : //www.linfo.org/file_command.html


谢谢,那, but without any option :( ... I've now also tried a mixof UTF-16 and UTF-8 and ISO-8859-1. 行得通。。。我试过'file file -i` report unknown-8bit。因此,这似乎也可以解决以下问题:“如何检测无效/未知编码”
Peter.O 2011年

对于那些到达这里并在Mac上使用的用户,它file -I以大写的“ i”代替小写。
samuraiseoul

21

并非总是可以确定地确定文本文件的编码是什么。例如,字节序列\303\275c3 bd以十六进制表示)可以ý在UTF-8中,ý在latin1中,Ă˝在latin2中或在BIG-5中,依此类推。

有些编码的字节序列无效,因此可以肯定地将它们排除在外。对于UTF-8尤其如此;大多数8位编码的大多数文本都是无效的UTF-8。您可以使用isutf8来自moreutils或与一起测试有效的UTF-8 iconv -f utf-8 -t utf-8 >/dev/null

有些工具会尝试猜测文本文件的编码。它们可能会犯错误,但只要您不故意欺骗他们,它们通常就会在实践中起作用。

  • file
  • PerlEncode::Guess(标准分发的一部分)尝试对字节字符串进行连续编码,并返回该字符串为有效文本的第一个编码。
  • Enca是编码猜测器和转换器。您可以为其指定一个语言名称和文本(支持的语言主要是东欧语言),然后尝试猜测编码。

如果文件中有元数据(HTML / XML charset=,TeX \inputenc,emacs -*-coding-*-…),则高级编辑器(例如Emacs或Vim)通常能够解析该元数据。但是,从命令行自动化并不容易。


感谢您的很好的概述...是的,“最好的猜测”,可当编码是不知道的唯一选择......用iconv,我只是跑所有1168个编码(包括别名)上市iconv -l对我的.htm文件一个...有683个编码通过了标记。.文件的实际字符集= ISO-8859-1 ..由所有小节1 ASCII范围值组成。.非ASCII字符为\ xA9。
Peter.O 2011年

0

另外,如果您使用文件-i给您未知

您可以使用此php命令来猜测字符集,如下所示:

在php中,您可以像下面这样检查:

明确指定编码列表:

php -r "echo 'probably : ' . mb_detect_encoding(file_get_contents('myfile.txt'), 'UTF-8, ASCII, JIS, EUC-JP, SJIS, iso-8859-1') . PHP_EOL;"

更准确的“ mb_list_encodings ”:

php -r "echo 'probably : ' . mb_detect_encoding(file_get_contents('myfile.txt'), mb_list_encodings()) . PHP_EOL;"

在第一个示例中,您可以看到我放置了可能匹配的编码列表(检测列表顺序)。为了获得更准确的结果,您可以通过mb_list_encodings()使用所有可能的编码

注意mb_ *函数需要php-mbstring

apt-get install php-mbstring 

查看答案:https : //stackoverflow.com/a/57010566/3382822

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.