Jika saya menjalankan program Perl berikut:
perl -e 'use utf8; print "鸡\n";'
Saya mendapatkan peringatan ini:
Wide character in print at -e line 1.
Jika saya menjalankan program Perl ini:
perl -e 'print "鸡\n";'
Saya tidak mendapat peringatan.
Saya pikir use utf8
saya harus menggunakan karakter UTF-8 dalam skrip Perl. Mengapa ini tidak berhasil dan bagaimana cara memperbaikinya? Saya menggunakan Perl 5.16.2. Saya memiliki masalah yang sama jika ini ada dalam file alih-alih menjadi satu liner pada baris perintah.
Jawaban:
Tanpa
use utf8
Perl menafsirkan string Anda sebagai urutan karakter byte tunggal. Ada empat byte dalam string Anda seperti yang Anda lihat dari ini:$ perl -E 'say join ":", map { ord } split //, "鸡\n";' 233:184:161:10
Tiga byte pertama membentuk karakter Anda, yang terakhir adalah feed baris.
Panggilan untuk
print
mengirimkan empat karakter ini ke STDOUT. Konsol Anda kemudian mengetahui cara menampilkan karakter ini. Jika konsol Anda disetel untuk menggunakan UTF8, maka tiga byte tersebut akan ditafsirkan sebagai karakter tunggal Anda dan itulah yang ditampilkan.Jika kita menambahkan
utf8
modul, semuanya berbeda. Dalam hal ini, Perl menafsirkan string Anda hanya sebagai dua karakter.$ perl -Mutf8 -E 'say join ":", map { ord } split //, "鸡\n";' 40481:10
Secara default, lapisan IO Perl mengasumsikan bahwa ia bekerja dengan karakter byte tunggal. Jadi ketika Anda mencoba untuk mencetak karakter multi-byte, Perl berpikir ada sesuatu yang salah dan memberi Anda peringatan. Seperti biasa, Anda bisa mendapatkan lebih banyak penjelasan untuk kesalahan ini dengan menyertakan
use diagnostics
. Ini akan mengatakan ini:Seperti yang ditunjukkan orang lain, Anda perlu memberi tahu Perl untuk menerima keluaran multi-byte. Ada banyak cara untuk melakukan ini (lihat Tutorial Perl Unicode untuk beberapa contoh). Salah satu cara paling sederhana adalah dengan menggunakan tanda
-CS
baris perintah - yang memberi tahu tiga penanganan file standar (STDIN, STDOUT dan STDERR) untuk menangani UTF8.$ perl -Mutf8 -e 'print "鸡\n";' Wide character in print at -e line 1. 鸡
vs.
$ perl -Mutf8 -CS -e 'print "鸡\n";' 鸡
Unicode adalah area yang besar dan kompleks. Seperti yang Anda lihat, banyak program sederhana tampaknya melakukan hal yang benar, tetapi untuk alasan yang salah. Ketika Anda mulai memperbaiki bagian dari program, keadaan akan sering menjadi lebih buruk sampai Anda telah memperbaiki semua program.
sumber
-Mutf8
jika tidak dalam satu liner perl?use utf8;
Semua
use utf8;
tidak memberi tahu Perl bahwa kode sumber dikodekan menggunakan UTF-8. Anda perlu memberi tahu Perl cara menyandikan teks Anda:use open ':std', ':encoding(UTF-8)';
sumber
Encode semua keluaran standar sebagai UTF-8:
binmode STDOUT, ":utf8";
sumber
use open ':std', ':encoding(UTF-8)';
seperti yang diajukan oleh jawaban lain melakukan ini untuk STDOUT tetapi juga menandai STDERR, dan STDIN sebagai UTF-8, jadi Anda mendapatkan tiga untuk harga satu pernyataan. Lihat juga stackoverflow.com/a/42194059Anda bisa mendekati "lakukan saja utf8 di mana saja" dengan menggunakan modul CPAN
utf8::all
.perl -Mutf8::all -e 'print "鸡\n";'
Saat
print
menerima sesuatu yang tidak dapat dicetak (karakter lebih besar dari 255 jika tidak ada:encoding
lapisan yang disediakan), ia menganggap Anda bermaksud untuk mengenkodenya menggunakan UTF-8. Ia melakukannya, setelah peringatan tentang masalah tersebut.sumber
Anda bisa menggunakan ini,
Ini juga akan menghentikan kesalahan itu.
sumber
Dalam bahasa Spanyol Anda dapat menemukan kesalahan ini ketika di samping mulai menggunakan:
use utf8;
Encoding editor Anda berada dalam encoding yang berbeda. Jadi apa yang Anda lihat di editor bukanlah apa yang Perl lakukan. Untuk mengatasi kesalahan itu, cukup ubah encoding editor ke Unicode / UTF-8 .
sumber