/ / Perl UTF8 výstup do premennej - perl, utf-8

Perl UTF8 výstup na premennú - perl, utf-8

Mám nasledujúci kód Perlu, v ktorom otváram popisovač skalárnej premennej a zapisujem do neho nejaký text 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;

a keď ho spustím, dostanem nasledujúci výstup:

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

(bez upozornení alebo chýb). Takže, samozrejme, písanie utf8 reťazca do premennej cez rukoväť tu nefunguje správne, pretože reťazec sa zdá byť dvojkódovaný. Snažil som sa otvoriť >:raw, >:bytes, >:encoding(ascii), ale nič z toho nepomohlo.

Možno som robil niečo hlúpe, ale nemôžem zistiť, ako to vyriešiť. Nejaké nápady?

odpovede:

7 pre odpoveď č. 1

Po prvé, :encoding(utf8) by mala byť :encoding(utf-8).

  • utf-8 je dobre známy štandard kódovania.
  • utf8 je rozšírenie špecifické pre Perl k utf-8.

referencie

(Názvy kódovania nie sú citlivé na veľkosť písmen.)


use open qw( :std :encoding(utf8) ); má dva účinky:

  • Dodáva :encoding(utf8) na STDIN, STDOUT a STDERR.
  • Nastaví predvolenú vrstvu pre open v lexikálnom rozsahu use na :encoding(utf8).

takže,

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;

Pokúsili ste sa potlačiť druhý efekt use open Ak chcete získať súbor kódových bodov Unicode, ale to je zbytočné, pretože súbory môžu obsahovať iba bajty. Niektoré typy kódovania alebo zlyhania sa musia vyskytnúť, ak sa pokúsite uložiť do súboru niečo iné ako bajty.

Takže žiť s ním, a dekódovať "súbor" pred použitím.

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;

Je možné sa tomu vyhnúť decode priamo v utf-8 v druhej polovici 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;

To samozrejme znamená, že nemôžete použiť $text_utf8 kdekoľvek, čo očakáva dekódovaný text.