![如何测试文本文件的编码...它是否有效?它是什么?](https://linux22.com/image/1317/%E5%A6%82%E4%BD%95%E6%B5%8B%E8%AF%95%E6%96%87%E6%9C%AC%E6%96%87%E4%BB%B6%E7%9A%84%E7%BC%96%E7%A0%81...%E5%AE%83%E6%98%AF%E5%90%A6%E6%9C%89%E6%95%88%EF%BC%9F%E5%AE%83%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F.png)
我有几个.htm
打开的文件编辑器没有任何警告/错误,但是当我在 中打开这些相同的文件时Jedit
,它警告我无效的 UTF-8 编码...
HTML 元标记声明“charset=ISO-8859-1”。 Jedit 允许后备编码列表和一个编码自动检测器列表(目前为“BOM XML-PI”),所以我眼前的问题已经解决了。但这让我思考:如果元数据不存在怎么办?
当编码信息不可用时,是否有一个 CLI 程序可以对可能适用的编码进行“最佳猜测”?
而且,尽管这是一个略有不同的问题;是否有一个 CLI 程序可以测试已知的编码?
答案1
该file
命令对编码进行“最佳猜测”。
这里演示了一个包含以 utf-8 编码的德语变音符号的文件:
$ file umlaut-utf8.txt
umlaut-utf8.txt: UTF-8 Unicode text
其他两种编码中的变音符号相同:
$ file umlaut-iso88591.txt umlaut-utf16.txt
umlaut-iso88591.txt: ISO-8859 text
umlaut-utf16.txt: Little-endian UTF-16 Unicode text, with no line terminators
所有这三个混在一起导致无效编码:
$ file umlaut-mixed.txt
umlaut-mixed.txt: data
可以使用该-i
参数以mime类型输出:
$ 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
(在 Mac 上是这样-I
。因为苹果开发人员的想法不同。)
该file
命令非常有限。它会检查一些字节并尝试猜测编码可能是什么。如果它识别出一个模式,它会说它是这个或那个编码。如果它无法识别某个模式,或者所识别的模式相互矛盾,它会显示“数据”(或 mime 类型中的二进制)。这实际上意味着无法识别有效的编码。
这类似于您根据字符和元音变音的分布来识别文本是西班牙语还是法语。如果您收到的文本中字符的分布毫无意义,那么您可能会得出结论,它是“无效”文本。但它可能是一种您以前从未见过的语言。将此与 Lorem Ipsum 进行比较。文字为看就像自然文本,但实际上是无意义的:https://en.wikipedia.org/wiki/Lorem_ipsum
file
这是一个无法识别正确编码的示例:查看包含 DOS 文本(方框图字符、CRLF 行终止符)和转义序列的文件
以下是有关该file
命令的更多信息:http://www.linfo.org/file_command.html
我如何创建文件:
$ echo ä > umlaut-utf8.txt
您可以复制此行并运行它。它应该创建一个包含 utf8 元音变音的文件。
检查十六进制转储:
$ hexdump -C umlaut-utf8.txt
00000000 c3 a4 0a |...|
00000003
转换为其他编码:
$ 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
与之比较https://en.wikipedia.org/wiki/ä#Computer_encoding
通过混合所有三个来创建“无效”的东西:
$ cat umlaut-iso88591.txt umlaut-utf8.txt umlaut-utf16.txt > umlaut-mixed.txt
答案2
并不总是能够确定文本文件的编码是什么。例如,字节序列\303\275
(c3 bd
十六进制)可以ý
采用 UTF-8、ý
latin1、Ă˝
latin2 或羸
BIG-5 等。
某些编码具有无效的字节序列,因此可以肯定地排除它们。对于 UTF-8 尤其如此;大多数 8 位编码中的大多数文本都不是有效的 UTF-8。您可以使用isutf8
from测试有效的 UTF-8更多实用程序或与iconv -f utf-8 -t utf-8 >/dev/null
等。
有些工具会尝试猜测文本文件的编码。他们可能会犯错误,但只要你不刻意愚弄他们,他们在实践中通常会起作用。
file
- 珀尔
Encode::Guess
(标准发行版的一部分)尝试对字节字符串进行连续编码,并返回该字符串是有效文本的第一个编码。 - 恩卡是一个编码猜测器和转换器。您可以给它一个语言名称和您认为是该语言的文本(支持的语言主要是东欧语言),它会尝试猜测编码。
如果文件中有元数据(HTML/XML charset=
、TeX \inputenc
、emacs-*-coding-*-
等),Emacs 或 Vim 等高级编辑器通常能够解析该元数据。不过,从命令行实现自动化并不容易。
答案3
我认为这CLI 工具可能正是您所寻找的!
确保已安装 Node.js 和 NPM:
$ sudo apt install nodejs npm
安装 CLI:
$ npm install -g detect-file-encoding-and-language
使用 CLI:
$ dfeal "/home/user name/Documents/subtitle file.srt"
# Possible result: { language: french, encoding: CP1252, confidence: 0.99 }
答案4
另外,如果你 file -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