3

次のような文字列があります。

Why RUNAS Windows \xee\x80\x80\x45xplorer\xee\x80\x81 Doesn\xe2\x80\x99t 
Work After Installing IE7 St\xc3\xa5le

XML ファイルを読み取って取得します。これは UTF-8 文字列です。次に、同等の Unicode 文字を出力して、次のようにします。

Why RUNAS Windows Explorer Doesn’t Work After Installing IE7 Ståle 

私は小さなプログラムを試しました:

use strict;
use utf8;
use Encode;

my $str = "Why RUNAS Windows \xee\x80\x80\x45xplorer\xee\x80\x81 Doesn\xe2\x80\x99t Work After Installing IE7 St\xc3\xa5le";
print $str;

そしてそれは働いた!!

問題は、ファイルから文字列を読み込もうとしているときに変換されないことです。したがって、以下は unicode 出力を生成しません。

use strict;
use utf8;
use Encode;
my $str = <DATA>;
$str = decode("utf8", $str);
open OUT, ">", "o.txt" or die;
binmode(OUT,":utf8");
print OUT $str;
__DATA__
Why RUNAS Windows \xee\x80\x80\x45xplorer\xee\x80\x81 Doesn\xe2\x80\x99t Work After Installing IE7 St\xc3\xa5le
4

3 に答える 3

6

2 つの例の違いは、最初の例のバックスラッシュがコンパイル時にバイトとして補間されているのに対し、2 番目の例ではリテラル テキストであることです。2 番目の例では一連の文字 "\"、"x"、"e"、"e" を読み取っていますが、最初の例ではそれをメモリ内の 1 つの Unicode 文字に変換しています。

XML ファイルに Unicode 文字が含まれている場合、Perl はそれらを問​​題なく読み取ることができます。示されているようにエスケープする必要はありません。

これらの Unicode 文字を一連の文字として保持する必要がある場合は、CPAN のライブラリを使用してデコードすることを検討してください。一見すると、Encode::Escapeがニーズを満たしているように見えます。

#!/usr/bin/perl
use strict;
use warnings;
use Encode::Escape;

while (<DATA>) {
    chomp;
    print decode 'unicode-escape', $_; # convert byte references to (utf-8) bytes
}

__DATA__
Why RUNAS Windows \xee\x80\x80\x45xplorer\xee\x80\x81 Doesn\xe2\x80\x99t
Work After Installing IE7 St\xc3\xa5le

他にもあるかもしれません。

于 2013-01-09T17:13:44.767 に答える
4

これは明らかです:

print "abc\n";   # Prints <abc>

<DATA>;          # Doesn't print <abc>
__DATA__
print "abc\n";

したがって、これは当然のことです。

"\x61";          # Evaluates to string <a>

<DATA>;          # Doesn't evaluate to string <a>
__DATA__
"\x61"

文字列リテラル (Perl 演算子) と文字列 (一連の文字) を混同しています。readlineデータ ファイルを Perl コードとして実行しません。(あったとしても、引用符がありませんでした。) 読み取った文字列を変換したい場合は、Perl にそれらを変換するように指示する必要があります。

s/ \\x(..) | \\([^a-zA-Z]) | \\(.) /
   defined($1) ? chr(hex($1)) :
   defined($2) ? $2 :
   do { warn "Unknown escape \\$3\n"; "\\$3" }
/sexg;
于 2013-01-09T17:20:22.983 に答える
1

各コードを対応するバイトに変更するには、評価による置換を使用します。いいえ、必要ありuse utf8ませんuse Encode:

#!/usr/bin/perl
use warnings;
use strict;

my $str = <DATA>;
$str =~ s/\\x(..)/chr hex $1/eg;
open my $OUT, '>', 'o.txt' or die $!; # No binmode utf8 - byte semantics needed!
print $OUT $str;

__DATA__
Why RUNAS Windows \xee\x80\x80\x45xplorer\xee\x80\x81 Doesn\xe2\x80\x99t Work After Installing IE7 St\xc3\xa5le
于 2013-01-09T17:13:39.957 に答える