Yes!
显然,最好修复创建文件的程序,但这并不总是可行。以下是两种解决方案。
一行可以包含多种编码
编码::修复拉丁语 http://search.cpan.org/perldoc?Encoding::FixLatin提供了一个名为fix_latin
它解码由 UTF-8、iso-8859-1、cp1252 和 US-ASCII 混合组成的文本。
$ perl -e'
use Encoding::FixLatin qw( fix_latin );
$bytes = "\xD0 \x92 \xD0\x92\n";
$text = fix_latin($bytes);
printf("U+%v04X\n", $text);
'
U+00D0.0020.2019.0020.0412.000A
虽然采用了启发式方法,但它们相当可靠。只有以下情况才会失败:
One of
[ÀÁÁÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß]
使用 iso-8859-1 或 cp1252 编码,后跟其中之一
[€‚▪„...†‡ˆ‰Š´ŒŽ‘’“”•–—~™š›œžŸ<NBSP>
�£¤¥�§�©ª«�<SHY>
® ́°±23´µ¶·¸1º»1/43¿]
使用 iso-8859-1 或 cp1252 编码。
One of
[àáâãäåæçèééêëìíîï]
使用 iso-8859-1 或 cp1252 编码,后跟其中的两个
[€‚▪„...†‡ˆ‰Š´ŒŽ‘’“”•–—~™š›œžŸ<NBSP>
�£¤¥�§�©ª«�<SHY>
® ́°±23´µ¶·¸1º»1/43¿]
使用 iso-8859-1 或 cp1252 编码。
One of
[ðñòóôõöö]
使用 iso-8859-1 或 cp1252 编码,后跟其中的两个
[€‚▪„...†‡ˆ‰Š´ŒŽ‘’“”•–—~™š›œžŸ<NBSP>
�£¤¥�§�©ª«�<SHY>
® ́°±23´µ¶·¸1º»1/43¿]
使用 iso-8859-1 或 cp1252 编码。
使用核心模块可以产生相同的结果Encode http://search.cpan.org/perldoc?Encode,尽管我认为这比安装了 Encoding::FixLatin::XS 的 Encoding::FixLatin 要慢一些。
$ perl -e'
use Encode qw( decode_utf8 encode_utf8 decode );
$bytes = "\xD0 \x92 \xD0\x92\n";
$text = decode_utf8($bytes, sub { encode_utf8(decode("cp1252", chr($_[0]))) });
printf("U+%v04X\n", $text);
'
U+00D0.0020.2019.0020.0412.000A
每行仅使用一种编码
fix_latin
在角色级别上起作用。如果已知每一行完全使用 UTF-8、iso-8859-1、cp1252 或 US-ASCII 之一进行编码,则可以通过检查该行是否是有效的 UTF-8 来使该过程更加可靠。
$ perl -e'
use Encode qw( decode );
for $bytes ("\xD0 \x92 \xD0\x92\n", "\xD0\x92\n") {
if (!eval {
$text = decode("UTF-8", $bytes, Encode::FB_CROAK|Encode::LEAVE_SRC);
1 # No exception
}) {
$text = decode("cp1252", $bytes);
}
printf("U+%v04X\n", $text);
}
'
U+00D0.0020.2019.0020.00D0.2019.000A
U+0412.000A
采用启发式方法,但它们非常可靠。他们只会失败,如果all对于给定的行,以下选项正确:
该行使用 iso-8859-1 或 cp1252 进行编码,
至少其中之一
[€‚▪„...†‡ˆ‰Š´ŒŽ‘’“”•–—~™š›œžŸ<NBSP>
�£¤¥�§�©ª«�<SHY>
®̿°±23´µ¶·¸1º»¼½⁄¿ÀÁÁÊÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷]
存在于该行中,
的所有实例
[ÀÁÁÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß]
总是紧随其后的是其中之一
[€‚▪„...†‡ˆ‰Š´ŒŽ‘’“”•–—~™š›œžŸ<NBSP>
�£¤¥�§�©ª«�<SHY>
® ́°±23´µ¶·¸1º»1/23¿],
的所有实例
[àáâãäåæçèééêëìíîï]
总是紧随其后的是两个
[€‚▪„...†‡ˆ‰Š´ŒŽ‘’“”•–—~™š›œžŸ<NBSP>
�£¤¥�§�©ª«�<SHY>
® ́°±23´µ¶·¸1º»1/23¿],
的所有实例
[ðñòóôõöö]
后面总是紧接着三个
[€‚▪„...†‡ˆ‰Š´ŒŽ‘’“”•–—~™š›œžŸ<NBSP>
�£¤¥�§�©ª«�<SHY>
® ́°±23´µ¶·¸1º»1/23¿],
None of
[呸呸呸呸]
存在于该行中,并且
None of
[€‚▪„...†‡ˆ‰Š´ŒŽ‘’“”•–—~™š›œžŸ<NBSP>
�£¤¥�§�©ª«�<SHY>
® ́°±23´µ¶·¸1º»1/43¿]
除了前面提到的之外,都存在于该行中。
Notes:
- Encoding::FixLatin 安装命令行工具
fix_latin
转换文件,使用第二种方法编写一个文件会很简单。
-
fix_latin
(函数和文件)可以通过安装来加速编码::FixLatin::XS http://search.cpan.org/perldoc?Encoding::FixLatin::XS.
- 相同的方法可用于 UTF-8 与其他单字节编码的混合。可靠性应该相似,但也可能有所不同。