ike*_*ami 11 perl encoding character-encoding
我有一个生成UTF-8文件的应用程序,但有些内容编码不正确.一些字符编码为iso-8859-1 aka iso-latin-1或cp1252 aka Windows-1252.有没有办法恢复原始文本?
ike*_*ami 11
是!
显然,最好修复创建文件的程序,但这并不总是可行的.以下是两种解决方案.
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
Run Code Online (Sandbox Code Playgroud)
采用启发式方法,但它们相当可靠.只有以下情况才会失败:
之一的
[ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞß]
使用ISO-8859-1或CP1252,随后之一编码
[€,ƒ"...†‡‰Š<OEZ '''’•--~™S>œžŸ <NBSP>¡¢£¤ 使用iso-8859-1或cp1252编码¥| <SHY>§¨ªª¬¬¯°±³³'μ·¸¹º»¼½¾¿
其中一个
[àáâåäåæçèéêëìíï]
使用iso-8859-1或cp1252编码,然后是两个
[€,ƒ"...†‡‰<ŒŽ''""• - 〜™š>œžŸ¢¢ <NBSP>¥ §©ª«¬ <SHY>®°±²³'μ·¸¹º»¼½¾¿]
使用ISO-8859-1或CP1252编码.
其中一个
[ðñòóôõö÷]
使用iso-8859-1或cp1252编码,然后是两个
[€,ƒ"...†‡‰<ŒŽ''""• - 〜™š>œžŸ¢¢ <NBSP>¥ 使用iso-8859-1或cp1252编码| <SHY>§ « ¬®¯°±³³'μ·¸¹º»¼½¾¿
使用核心模块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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
采用启发式方法,但它们非常可靠.如果给定行的所有以下内容均为真,则它们将失败:
该行使用iso-8859-1或cp1252进行编码,
至少有一个
[€,ƒ"...†‡‰<ŒŽ''""• - 〜™š>œžŸ¢¢ <NBSP>¥|§«¬« <SHY>¯®¯°±³³μμ· ¸¹º»¼½¾¿ÀÁÂÃ¼ÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷]
出现在该行,
所有
[ÀÁÃ¼ÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞß]的
实例总是紧跟着
[€,ƒ"......†‡‰<ŒŽ''""• - 〜™š>œžŸ¢¢ <NBSP>¥|§|ª « <SHY>¬®¯°±³³'μ·¸¹º»¼½¾¿],
[àáâããååæçèéêëìíïï]的所有实例
后面总是紧跟着两个
[€,ƒ"...†‡‰<ŒŽ''""• - 〜™š>œžŸ¢¢ <NBSP>¥|§«¬«¬ <SHY>®°±²³'μ·¸¹º»¼½¾¿]
[ðñòóôõ÷]的所有实例
后面总是紧跟三个
[€,ƒ"...†‡‰<ŒŽ''""• - 〜™š>œžŸ¢¢ <NBSP>¥|§«ª« ¬ <SHY>®°±²³'μ·¸¹º»¼½¾¿]
行中没有
[øùúûüýþÿ]
,和
没有
[€,ƒ"...†‡‰<ŒŽ''""• - 〜™š>œžŸ¢¢ <NBSP>¥|§«¬« <SHY>¬®¯°±³³'μ·¸¹º
除非前面提到过,否则行中存在»¼½¾¿
笔记:
fix_latin来转换文件,使用第二种方法编写一个是很简单的.fix_latin(函数和文件)可以通过安装Encoding :: FixLatin :: XS来加速.这是我编写Unicode :: UTF8的原因之一.使用Unicode :: UTF8,这在使用Unicode :: UTF8 :: decode_utf8()中的回退选项时是微不足道的.
use Unicode::UTF8 qw[decode_utf8];
use Encode qw[decode];
print "UTF-8 mixed with Latin-1 (ISO-8859-1):\n";
for my $octets ("\xD0 \x92 \xD0\x92\n", "\xD0\x92\n") {
no warnings 'utf8';
printf "U+%v04X\n", decode_utf8($octets, sub { $_[0] });
}
print "\nUTF-8 mixed with CP-1252 (Windows-1252):\n";
for my $octets ("\xD0 \x92 \xD0\x92\n", "\xD0\x92\n") {
no warnings 'utf8';
printf "U+%v04X\n", decode_utf8($octets, sub { decode('CP-1252', $_[0]) });
}
Run Code Online (Sandbox Code Playgroud)
输出:
UTF-8 mixed with Latin-1 (ISO-8859-1):
U+00D0.0020.0092.0020.0412.000A
U+0412.000A
UTF-8 mixed with CP-1252 (Windows-1252):
U+00D0.0020.2019.0020.0412.000A
U+0412.000A
Run Code Online (Sandbox Code Playgroud)
Unicode :: UTF8是用C/XS编写的,只在遇到生成错误的UTF-8序列时调用回调/回退.
| 归档时间: |
|
| 查看次数: |
2124 次 |
| 最近记录: |