如何检测latin1和UTF-8? [英] How to detect latin1 and UTF-8?

查看:189
本文介绍了如何检测latin1和UTF-8?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从XML文件中提取字符串,即使它是纯UTF-8,它不是。我的想法是

 #!/ usr / bin / perl 
使用警告;
使用strict;
使用编码qw(解码编码);
使用Data :: Dumper;

我的$ x =m\x {e6} gtig;
my $ y =m\x {c3} \x {a6} gtig;

我的$ a = encode('UTF-8',$ x);
my $ b = encode('UTF-8',$ y);

print Dumper $ x;
print Dumper $ y;
打印Dumper $ a;
print Dumper $ b;

if($ x eq $ y){print1\\\
; }
if($ x eq $ a){print2\\\
; }
if($ a eq $ y){print3\\\
; }
if($ a eq $ b){print4\\\
; }
if($ x eq $ b){print5\\\
; }
if($ y eq $ b){print6\\\
;

输出

 code> $ VAR1 ='m gtig'; 
$ VAR1 ='mægtig';
$ VAR1 ='mægtig';
$ VAR1 ='mÃ|gtig';根据这样的想法,只有一个latin1字符串会增加其长度,而是编码一个字符串,而
3



<已经UTF-8也使得它更长。所以我无法以这种方式检测到latin1和UTF-8。



问题



我想最终总是使用UTF-8字符串,但是如何检测它是latin1还是UTF-8,所以我只能转换latin1字符串?



如果一个字符串是UTF-8,可以得到一个yes / no。

解决方案

由于UTF-8的一些属性,使用iso-8859-1编码的文本不太可能是有效的UTF-8,除非使用两个编码 [1] 相同地解码。



因此,解决方案是尝试使用UTF-8进行解码。如果失败,则使用iso-8859-1进行解码。因为使用iso-8859-1的解码是一个no-op,我将跳过这一步。




  • utf8 ::实现:

      my $ decoded_text = $ utf8_or_latin1; 
    utf8 :: decode($ decoded_text);


  • Encode :: implementation:

     使用编码qw(decode_utf8); 

    我的$ decoded_text =
    eval {decode_utf8($ utf8_or_latin1,Encode :: FB_CROAK | Encode :: LEAVE_SRC)}
    // $ utf8_or_latin1;







现在,你说你想要UTF-8。 UTF-8从编码解码的文本获得。




  • utf8 :: implementation:

      my $ utf8 = $ decoded_text; 
    utf8 :: encode($ utf8);


  • Encode :: implementation:

     使用编码qw(encode_utf8); 

    我的$ utf8 = encode_utf8($ decoded_text);







Notes


  1. 假设文本是有效的UTF-8或有效的iso-8859-1,我的解决方案只会猜测如果满足以下所有条件,则为错误:




    • 文本使用iso-8859-1(与UTF-8相反)进行编码,

    • [
      < 80>< 81>< 82>< 83>< 85>< 86>< 87 >< 88>< 89>< 8A>< 8B>< 8C>< 8D>< 8E>< 8F>结果,< 90>< 91>< 92>< 93>< 94>< 95>< 96>< 97>< 98>< 99>< 9A>< 9B>< 9C>< 9D>< 9E>< 9F>结果< NBSP>&#XA1;&#XA2;&#XA3;&#XA4;&#xA5;&#xA6;&#XA7;&#xA8;&#xA9;&#XAA;&#XAB ;&#XAC;< SHY>&#XAE;&#XAF;&#XB0;&#XB1;&#XB2;&#XB3;&#XB4;&#XB5;&#XB6;&#XB7;& #XB8;&#xB9;&#XBA;&#XBB;&#XBC;&#XBD;&#XBE;&#XBF;结果&#XC0;&#XC1;&#XC2;&#XC3; &#XC4;&#XC5;&#XC6;&#xC7;&#xC8;&#xC9;&#XCA;&#XCB;&#XCC;&#XCD;&#XCE;&#XCF;&# XD0;&#XD1;&#XD2;&#XD3;&#XD4;&#XD5;&#XD6;&#XD7;&#XD8;&#xD9;&#XDA;&#XDB;&#XDC; &#的xDD;&#XDE;&#XDF;结果&#xE0;&#XE1;& #XE2;&#XE3;&#XE4;&#xE5;&#XE6;&#XE7;&#xE8;&#xE9;&#XEA;&#XEB;&#XEC;&#XED;&#XEE ;&#xEF;&#xF0;&#xF1;&#xF2;&#xF3;&#xF4;&#xF5;&#xF6;&#xF7;
      ]存在,

    • [&#xC0;&#xC1;&#xC2;&#xC3;&#xC4;&#xC5;&#xC6;&#xC7;&#xC8;&#xC9;& #xCA;&#XCB;&#XCC;&#XCD;&#XCE;&#XCF;&#XD0;&#XD1;&#XD2;&#XD3;&#XD4;&#XD5;&#XD6 ;&#xD7;&#xD8;&#xD9;&#xDA;&#xDB;&#xDC;&#xDD;&#xDE;&#xDF;]之后是[
      < 80 >< 81>< 82>< 83>< 84>< 85>的86>< 87>< 88>< 89>< 8A>< 8B>< 8C>< ; 8D>< 8E>< 8F>结果,< 90>< 91>< 92>< 93>< 94>< 95>< 96>< 97>< 98> < 99>< 9A>< 9B>< 9C>< 9D>< 9E>< 9F>结果,< NBSP>&#XA1;&#XA2;&#XA3;&#XA4 ;&#xA5;&#xA6;&#XA7;&#xA8;&#xA9;&#XAA;&#XAB;&#XAC;< SHY>&#XAE;&#XAF;&#XB0;& #XB1;&#XB2;&#XB3;&#XB4;&#XB5;&#XB6;&#XB7;&#XB8;&#xB9;&#XBA;&#XBB;&#XBC;&#XBD ;&#xBE;&#xBF;],

    • [&#xE0;&#xE1;&#xE2;&#xE3;&#xE4;&#xE5; &#xE6;&#xE7;&#xE8;&#xE9;&#xEA;&#xEB;&#xEC;&#xED;&#xEE;&#xEF;]后面是两个[
      < 80> < 81>< 82>< 83>< 84>< 85>的86>< 87>< 88>< 89>< 8A>< 8B>< 8C>< 8D>< 8E>< 8F>结果,< 90>< 91>< 92>< 93>< 94>< 95>< 96>< 97>< 98>< 99>< 9A>< 9B>< 9C>< 9D>< 9E>< 9F>结果,< NBSP>&#XA1;&#XA2;&#XA3;&#XA4; &#XB0;;&#&#xA5;&#xA6;&#XA7;&#xA8;&#xA9;&#XAA;&#XAB;&#XAC;< SHY>&#XAE;&#XAF XB1;&#XB2;&#XB3;&#XB4;&#XB5;&#XB6;&#XB7;&#XB8;&#xB9;&#XBA;&#XBB;&#XBC;&#XBD; &#xBE;&#xBF;],

    • [&#xF0;&#xF1;&#xF2;&#xF3;&#xF4;&#xF5; #xF6;&#xF7;]之后是[
      < 80> 81>< 83>< 83>>< 85>< 86>< 87& ; 88>< 89>< 8A>< 8B>< 8C>< 8D>< 8E>< 8F>结果,< 90>< 91>< 92>< 93> < 94>< 95>< 96>< 97>< 98>< 99>< 9A>< 9B>< 9C>< 9D>< 9E>< 9F>
      < NBSP>&#XA1;&#XA2;&#XA3;&#XA4;&#xA5;&#xA6;&#XA7;&#xA8;&#xA9;&#XAA;&#XAB;& #xAC;< SHY>&#XAE;&#XAF;&#XB0;&#XB1;&#XB2;&#XB3;&#XB4;&#XB5;&#XB6;&#XB7;&#XB8 ;&#xB9;&#xBA;&#xBB;&#xBC;&#xBD;&#xBE;&#xBF;],

    • [&#xF8; # xF9;&#xFA;&#xFB;&#xFC;&#xFD;&#xFE;&#xFF;]存在,

    • [
      & 80>< 81>< 82>< 83>< 84>< 85>的86>< 87>< 88>< 89>< 8A>< 8B>< 8C> < 8D>< 8E>< 8F>结果,< 90>< 91>< 92>< 93>< 94>< 95>< 96>< 97>< 98 >< 99>< 9A>< 9B>< 9C>< 9D>< 9E>< 9F>结果,< NBSP>&#XA1;&#XA2;&#XA3;&# XA4;&#xA5;&#xA6;&#XA7;&#xA8;&#xA9;&#XAA;&#XAB;&#XAC;< SHY>&#XAE;&#XAF;&#XB0; &#XB1;&#XB2;&#XB3;&#XB4;&#XB5;&#XB6;&#XB7;&#XB8;&#xB9;&#XBA;&#XBB;&#XBC;&# xBD;&#xBE;&#xBF;
      ]除了之前提到的以外。



    &#x20;



    (< 80& ; 9F>是未分配或不可打印的控制字符,不知道哪个。)



    换句话说,该代码非常可靠。



I am extracting strings from an XML file, and even though it should be pure UTF-8, it is not. My idea was to

#!/usr/bin/perl
use warnings;
use strict;
use Encode qw(decode encode);
use Data::Dumper;

my $x = "m\x{e6}gtig";
my $y = "m\x{c3}\x{a6}gtig";

my $a = encode('UTF-8', $x);
my $b = encode('UTF-8', $y);

print Dumper $x;
print Dumper $y;
print Dumper $a;
print Dumper $b;

if ($x eq $y) { print "1\n"; }
if ($x eq $a) { print "2\n"; }
if ($a eq $y) { print "3\n"; }
if ($a eq $b) { print "4\n"; }
if ($x eq $b) { print "5\n"; }
if ($y eq $b) { print "6\n"; }

outputs

$VAR1 = 'm�gtig';
$VAR1 = 'mægtig';
$VAR1 = 'mægtig';
$VAR1 = 'mægtig';
3

under the idea that only a latin1 string would increase its length, but encoding an already UTF-8 also makes it longer. So I can't detect latin1 vs UTF-8 that way.

Question

I would like to end up with always UTF-8 string, but how can I detect if it is latin1 or UTF-8, so I only convert the latin1 string?

Being able to get a yes/no if a string is UTF-8 would be just as useful.

解决方案

Due to some properties of UTF-8, it's very unlikely that text encoded using iso-8859-1 would be valid UTF-8 unless it decodes identically using both encodings[1].

As such, the solution is to try decoding it using UTF-8. If it fails, decode it using iso-8859-1 instead. Since decoding using iso-8859-1 is a no-op, I'll be skipping that step.

  • utf8:: implementation:

    my $decoded_text = $utf8_or_latin1;
    utf8::decode($decoded_text);
    

  • Encode:: implementation:

    use Encode qw( decode_utf8 );
    
    my $decoded_text =
       eval { decode_utf8($utf8_or_latin1, Encode::FB_CROAK|Encode::LEAVE_SRC) }
          // $utf8_or_latin1;
    


Now, you say you want UTF-8. UTF-8 is obtained from encoding decoded text.

  • utf8:: implementation:

    my $utf8 = $decoded_text;
    utf8::encode($utf8);
    

  • Encode:: implementation:

    use Encode qw( encode_utf8 );
    
    my $utf8 = encode_utf8($decoded_text);
    


Notes

  1. Assuming the text is either valid UTF-8 or valid iso-8859-1, my solution would only guess wrong if all of the following are true:

    • The text is encoded using iso-8859-1 (as opposed to UTF-8),
    • At least one of [
      <80><81><82><83><84><85><86><87><88><89><8A><8B><8C><8D><8E><8F>
      <90><91><92><93><94><95><96><97><98><99><9A><9B><9C><9D><9E><9F>
      <NBSP>¡¢£¤¥¦§¨©ª«¬<SHY>®¯°±²³´µ¶·¸¹º»¼½¾¿
      ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß
      àáâãäåæçèéêëìíîïðñòóôõö÷
      ] is present,
    • All instances of [ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß] are followed by one of [
      <80><81><82><83><84><85><86><87><88><89><8A><8B><8C><8D><8E><8F>
      <90><91><92><93><94><95><96><97><98><99><9A><9B><9C><9D><9E><9F>
      <NBSP>¡¢£¤¥¦§¨©ª«¬<SHY>®¯°±²³´µ¶·¸¹º»¼½¾¿],
    • All instances of [àáâãäåæçèéêëìíîï] are followed by two of [
      <80><81><82><83><84><85><86><87><88><89><8A><8B><8C><8D><8E><8F>
      <90><91><92><93><94><95><96><97><98><99><9A><9B><9C><9D><9E><9F>
      <NBSP>¡¢£¤¥¦§¨©ª«¬<SHY>®¯°±²³´µ¶·¸¹º»¼½¾¿],
    • All instances of [ðñòóôõö÷] are followed by three of [
      <80><81><82><83><84><85><86><87><88><89><8A><8B><8C><8D><8E><8F>
      <90><91><92><93><94><95><96><97><98><99><9A><9B><9C><9D><9E><9F>
      <NBSP>¡¢£¤¥¦§¨©ª«¬<SHY>®¯°±²³´µ¶·¸¹º»¼½¾¿],
    • None of [øùúûüýþÿ] are present, and
    • None of [
      <80><81><82><83><84><85><86><87><88><89><8A><8B><8C><8D><8E><8F>
      <90><91><92><93><94><95><96><97><98><99><9A><9B><9C><9D><9E><9F>
      <NBSP>¡¢£¤¥¦§¨©ª«¬<SHY>®¯°±²³´µ¶·¸¹º»¼½¾¿
      ] are present except where previously mentioned.

    (<80>..<9F> are unassigned or unprintable control characters, not sure which.)

    In other words, that code is very reliable.

这篇关于如何检测latin1和UTF-8?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆