decode_json
ожидает UTF-8, но вместо этого вы передаете декодированный текст (кодовые точки Unicode).
Таким образом, вы можете удалить существующее декодирование символов.
use feature qw( say );
use open 'std', ':encoding(UTF-8)';
use JSON qw( decode_json );
my $json_utf8 = do {
open(my $fh, '<:raw', $in_qfn)
or die("Can't open \"$in_qfn\": $!\n");
local $/;
<$fh>;
};
my $data = decode_json($json_utf8);
{
open(my $fh, '>', $out_qfn)
or die("Can't create \"$out_qfn\": $!\n");
for my $result (@{ $data->{results} }) {
say $fh $result->{text};
}
}
Или вы можете использовать from_json
(или JSON->new->decode
) вместо decode_json
.
use feature qw( say );
use open 'std', ':encoding(UTF-8)';
use JSON qw( from_json ); # <---
my $json_ucp = do {
open(my $fh, '<', $in_qfn) # <---
or die("Can't open \"$in_qfn\": $!\n");
local $/;
<$fh>;
};
my $data = from_json($json_ucp); # <---
{
open(my $fh, '>', $out_qfn)
or die("Can't create \"$out_qfn\": $!\n");
for my $result (@{ $data->{results} }) {
say $fh $result->{text};
}
}
Стрелки указывают на три незначительных различия между двумя фрагментами.
Я сделал несколько чисток.
- Отсутствует
local $/;
на случай, если в JSON есть разрывы строк. - Не используйте 2-arg
open
. - Не используйте ненужные глобальные переменные.
- Используйте более подходящие имена для переменных.
$data
и $json
были значительно изменены, а $file
не содержал файла. - Ограничьте область действия ваших переменных, особенно если они используют системные ресурсы (например, дескрипторы файлов).
- Используйте
:encoding(UTF-8)
(стандартная кодировка) вместо :encoding(utf8)
(кодировка, используемая только Perl).:utf8
еще хуже, поскольку он использует внутреннюю кодировку, а не стандартную, и может привести к повреждению скаляров при неправильном вводе. - Избавиться от зашумленных кавычек вокруг идентификаторов, используемых в качестве хэш-ключей.