/ / Perl UTF8 wyjście do zmiennej - perl, utf-8

Perl UTF8 wyjście do zmiennej - perl, utf-8

Mam następujący kod Perla, w którym otwieram uchwyt do zmiennej skalarnej i piszę do niej tekst utf8:

use warnings;
use strict;
use 5.010;
use utf8;
use open qw( :std :encoding(utf8) );

my $output;
open my $oh, ">", $output;
say $oh "Žluťoučký kůň.";
close $oh;

say "Žluťoučký kůň.";
print $output;

i kiedy go uruchomię, otrzymuję następujące wyniki:

Žluťoučký kůň.
ŽluÅ¥ouÄký kůÅ.

(bez ostrzeżeń i błędów). Więc, oczywiście, napisanie łańcucha utf8 do zmiennej za pomocą uchwytu nie działa tutaj poprawnie, ponieważ ciąg wydaje się być podwójnie zakodowany. Próbowałem otworzyć $ oh z >:raw, >:bytes, >:encoding(ascii), ale nic z tego nie pomogło.

Być może robię coś głupiego, ale nie potrafię tego naprawić. Jakieś pomysły?

Odpowiedzi:

7 dla odpowiedzi № 1

Po pierwsze, :encoding(utf8) powinno być :encoding(utf-8).

  • utf-8 jest dobrze znanym standardem kodowania.
  • utf8 jest specyficznym dla Perla rozszerzeniem do utf-8.

Odniesienie

(W nazwach kodowanych nie ma znaczenia wielkość liter).


use open qw( :std :encoding(utf8) ); ma dwa efekty:

  • Dodaje :encoding(utf8) do STDIN, STDOUT i STDERR.
  • Ustawia domyślną warstwę dla open w zakresie leksykalnym use do :encoding(utf8).

Więc,

use utf8;
use open qw( :std :encoding(utf-8) );

# String of decoded text aka string of Unicode Code Points, thanks to `use utf8`.
my $text_ucp = "Žluťoučký kůň.";

# $output will contain text encoded using utf-8 thanks to `use open`.
open my $oh, ">", my $text_utf8;
say $oh $text_ucp;
close $oh;

# ok. Will encode the decoded text using utf-8 thanks to `use open`.
say $text_ucp;

# XXX. Will encode the already-encoded text using utf-8 thanks to `use open`.
print $text_utf8;

Próbowałeś zastąpić drugi efekt use open aby uzyskać plik punktów kodowych Unicode, ale to daremne, ponieważ pliki mogą zawierać tylko bajty. Pewne rodzaje kodowania lub niepowodzenia muszą wystąpić, jeśli spróbujesz zapisać coś innego niż bajty w pliku.

Więc żyj z nim i dekoduj "plik" przed użyciem.

use utf8;
use open qw( :std :encoding(utf-8) );
use Encode qw( decode_utf8 );

my $text_ucp = "Žluťoučký kůň.";

open my $oh, ">", my $text_utf8;
say $oh $text_ucp;
close $oh;

my $text2_ucp = decode_utf8($text_utf8);

... Do stuff with $text_ucp and/or $text2_ucp ...

say $text_ucp;
say $text2_ucp;

Możliwe jest uniknięcie decode współpracując bezpośrednio z utf-8 w drugiej połowie programu.

use utf8;
BEGIN { binmode(STDERR, ":encoding(utf-8)"); }  # We"ll handle STDOUT manually.
use open qw( :encoding(utf-8) );
use Encode qw( encode_utf8 );

my $text_ucp = "Žluťoučký kůň.";

open my $oh, ">", my $text_utf8;
say $oh $text_ucp;
close $oh;

say encode_utf8($text_ucp);
say $text_utf8;

Oczywiście oznacza to, że nie możesz tego użyć $text_utf8 wszędzie, gdzie oczekuje się odkodowanego tekstu.