JSONライブラリで処理するとUTF-8文字が破棄されます(これはProblem with decoding unicode JSON in perlと似ていますが、binmodeを設定すると別の問題が発生します)。perlのUTF-8 JSONを解読する際の問題
は、私は、次の例にまで問題が低下している:
(hlovdal) localhost:/tmp/my_test>cat my_test.pl
#!/usr/bin/perl -w
use strict;
use warnings;
use JSON;
use File::Slurp;
use Getopt::Long;
use Encode;
my $set_binmode = 0;
GetOptions("set-binmode" => \$set_binmode);
if ($set_binmode) {
binmode(STDIN, ":encoding(UTF-8)");
binmode(STDOUT, ":encoding(UTF-8)");
binmode(STDERR, ":encoding(UTF-8)");
}
sub check {
my $text = shift;
return "is_utf8(): " . (Encode::is_utf8($text) ? "1" : "0") . ", is_utf8(1): " . (Encode::is_utf8($text, 1) ? "1" : "0"). ". ";
}
my $my_test = "hei på deg";
my $json_text = read_file('my_test.json');
my $hash_ref = JSON->new->utf8->decode($json_text);
print check($my_test), "\$my_test = $my_test\n";
print check($json_text), "\$json_text = $json_text";
print check($$hash_ref{'my_test'}), "\$\$hash_ref{'my_test'} = " . $$hash_ref{'my_test'} . "\n";
(hlovdal) localhost:/tmp/my_test>
テキストをテスト実行しているISO-8859-1にcrippeled何らかの理由です。 binmode sort ofを設定すると、それを解決しますが、他の文字列を二重にエンコードします。
(hlovdal) localhost:/tmp/my_test>cat my_test.json
{ "my_test" : "hei på deg" }
(hlovdal) localhost:/tmp/my_test>file my_test.json
my_test.json: UTF-8 Unicode text
(hlovdal) localhost:/tmp/my_test>hexdump -c my_test.json
0000000 { " m y _ t e s t " : " h
0000010 e i p 303 245 d e g " } \n
000001e
(hlovdal) localhost:/tmp/my_test>
(hlovdal) localhost:/tmp/my_test>perl my_test.pl
is_utf8(): 0, is_utf8(1): 0. $my_test = hei på deg
is_utf8(): 0, is_utf8(1): 0. $json_text = { "my_test" : "hei på deg" }
is_utf8(): 1, is_utf8(1): 1. $$hash_ref{'my_test'} = hei p� deg
(hlovdal) localhost:/tmp/my_test>perl my_test.pl --set-binmode
is_utf8(): 0, is_utf8(1): 0. $my_test = hei på deg
is_utf8(): 0, is_utf8(1): 0. $json_text = { "my_test" : "hei på deg" }
is_utf8(): 1, is_utf8(1): 1. $$hash_ref{'my_test'} = hei på deg
(hlovdal) localhost:/tmp/my_test>
この原因と解決方法は何ですか?
これは、新しくインストールされた最新のFedora 15システムにあります。
(hlovdal) localhost:/tmp/my_test>perl --version | grep version
This is perl 5, version 12, subversion 4 (v5.12.4) built for x86_64-linux-thread-multi
(hlovdal) localhost:/tmp/my_test>rpm -q perl-JSON
perl-JSON-2.51-1.fc15.noarch
(hlovdal) localhost:/tmp/my_test>locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
(hlovdal) localhost:/tmp/my_test>
更新:use utf8
を追加する文字がまだ(以前は若干異なるが)右に処理されていない、それを解決しない。
(hlovdal) localhost:/tmp/my_test>perl my_test.pl
is_utf8(): 1, is_utf8(1): 1. $my_test = hei p� deg
is_utf8(): 0, is_utf8(1): 0. $json_text = { "my_test" : "hei på deg" }
is_utf8(): 1, is_utf8(1): 1. $$hash_ref{'my_test'} = hei p� deg
(hlovdal) localhost:/tmp/my_test>perl my_test.pl --set-binmode
is_utf8(): 1, is_utf8(1): 1. $my_test = hei på deg
is_utf8(): 0, is_utf8(1): 0. $json_text = { "my_test" : "hei på deg" }
is_utf8(): 1, is_utf8(1): 1. $$hash_ref{'my_test'} = hei på deg
(hlovdal) localhost:/tmp/my_test>
で表されているようPerlソースでUnicodeを使用できますか?
はい、できます。ソースが UTF-8でエンコードされている場合は、utf8プラグマを使用して と指定できます。
use utf8;
これは、お客様の 入力、または出力には何も行いません。 は、あなたのソースが の方法に影響します。文字列 リテラルのUnicodeを識別子で使用することができます(ただし、 は\ wによれば "word characters" でなければなりません)。また、カスタムの 区切り文字でも使用できます。
なぜ-1が投票されましたか? – hlovdal