Không có use utf8
Perl diễn giải chuỗi của bạn là một chuỗi các ký tự byte đơn. Có bốn byte trong chuỗi của bạn như bạn có thể thấy từ sau:
$ perl -E 'say join ":", map { ord } split //, "鸡\n";'
233:184:161:10
Ba byte đầu tiên tạo nên nhân vật của bạn, byte cuối cùng là dòng cấp dữ liệu.
Lệnh gọi để print
gửi bốn ký tự này tới STDOUT. Bảng điều khiển của bạn sau đó sẽ tìm ra cách hiển thị các ký tự này. Nếu bảng điều khiển của bạn được đặt để sử dụng UTF8, thì nó sẽ diễn giải ba byte đó là ký tự đơn của bạn và đó là những gì được hiển thị.
Nếu chúng ta thêm vào utf8
mô-đun, mọi thứ sẽ khác. Trong trường hợp này, Perl diễn giải chuỗi của bạn chỉ là hai ký tự.
$ perl -Mutf8 -E 'say join ":", map { ord } split //, "鸡\n";'
40481:10
Theo mặc định, lớp IO của Perl giả định rằng nó đang hoạt động với các ký tự byte đơn. Vì vậy, khi bạn cố gắng in một ký tự nhiều byte, Perl nghĩ rằng có gì đó không ổn và đưa ra cảnh báo cho bạn. Như mọi khi, bạn có thể nhận được thêm lời giải thích cho lỗi này bằng cách bao gồm use diagnostics
. Nó sẽ nói thế này:
(S utf8) Perl đã gặp một ký tự rộng (> 255) khi nó không mong đợi một ký tự. Cảnh báo này được bật theo mặc định cho I / O (như in). Cách dễ nhất để giảm bớt cảnh báo này chỉ đơn giản là thêm lớp: utf8 vào đầu ra, ví dụ như binmode STDOUT, ': utf8'. Một cách khác để tắt cảnh báo là thêm không có cảnh báo nào 'utf8'; nhưng điều đó thường gần với gian lận hơn. Nói chung, bạn phải đánh dấu rõ ràng xử lý tệp bằng mã hóa, hãy xem mở và perlfunc / binmode.
Như những người khác đã chỉ ra, bạn cần yêu cầu Perl chấp nhận đầu ra nhiều byte. Có nhiều cách để thực hiện việc này (xem Hướng dẫn Perl Unicode để biết một số ví dụ). Một trong những cách đơn giản nhất là sử dụng -CS
cờ dòng lệnh - nó cho ba bộ xử lý tệp tiêu chuẩn (STDIN, STDOUT và STDERR) để đối phó với UTF8.
$ perl -Mutf8 -e 'print "鸡\n";'
Wide character in print at -e line 1.
鸡
vs
$ perl -Mutf8 -CS -e 'print "鸡\n";'
鸡
Unicode là một lĩnh vực lớn và phức tạp. Như bạn đã thấy, nhiều chương trình đơn giản dường như hoạt động đúng nhưng vì những lý do sai lầm. Khi bạn bắt đầu sửa một phần của chương trình, mọi thứ thường sẽ trở nên tồi tệ hơn cho đến khi bạn sửa xong tất cả chương trình.