问题描述
我正在从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,所以我只能转换latin1字符串?
如果一个字符串是UTF-8,可以得到一个yes / no。
由于UTF-8的一些属性,使用iso-8859-1编码的文本不太可能是有效的UTF-8,除非使用两个编码相同地解码。
因此,解决方案是尝试使用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
-
假设文本是有效的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.
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
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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!