Bez use utf8
Perl interpretuje twój ciąg jako ciąg znaków jednobajtowych. Istnieją cztery bajty w Twojej ciąg, jak widać z tego:
$ perl -E 'say join ":", map { ord } split //, "鸡\n";'
233:184:161:10
Pierwsze trzy bajty tworzą swoją postać, ostatni jest line-feed.
Połączenie z print
wysyła te cztery znaki do STDOUT. Twoja konsola następnie opracuje sposób wyświetlania tych znaków. Jeśli konsola jest skonfigurowana do używania UTF8, to zinterpretuje te trzy bajty jako swój pojedynczy znak i to jest to, co jest wyświetlane.
Jeśli dodamy moduł utf8
, wszystko wygląda inaczej. W takim przypadku Perl interpretuje twój ciąg jako tylko dwa znaki.
$ perl -Mutf8 -E 'say join ":", map { ord } split //, "鸡\n";'
40481:10
Domyślnie warstwa IO Perla zakłada, że działa ze znakami jednobajtowymi. Więc kiedy próbujesz wydrukować wielobajtową postać, Perl myśli, że coś jest nie tak i daje ci ostrzeżenie. Jak zawsze, możesz uzyskać więcej wyjaśnień tego błędu, włączając w to use diagnostics
. Będzie to powiedzieć:
(S utf8) Perl spotkał szeroki charakter (> 255), gdy nie spodziewałem jeden. To ostrzeżenie jest domyślnie włączone dla I/O (np. Drukowanie). Najprostszym sposobem, aby wyciszyć to ostrzeżenie, jest dodanie warstwy: utf8 do danych wyjściowych , np. binmode STDOUT, ": utf8". Innym sposobem na wyłączenie ostrzeżenia jest dodanie ostrzeżenia "utf8"; ale często jest to bliższe oszustwom z . Ogólnie rzecz biorąc, należy jawnie oznaczyć uchwyt pliku za pomocą kodowania, patrz tryb otwarty i perlfunc/bin.
Jak inni podkreślili, musisz powiedzieć Perlowi, aby zaakceptował wielobajtowe wyjście. Istnieje wiele sposobów, aby to zrobić (patrz: przykłady Perl Unicode Tutorial). Jednym z najprostszych sposobów jest użycie flagi linii komend -CS
- która mówi trzem standardowym uchwytom plików (STDIN, STDOUT i STDERR), aby poradzić sobie z UTF8.
$ perl -Mutf8 -e 'print "鸡\n";'
Wide character in print at -e line 1.
鸡
vs
$ perl -Mutf8 -CS -e 'print "鸡\n";'
鸡
Unicode jest duże i złożone zagadnienie. Jak widzieliśmy, wiele prostych programów wydaje się robić to, co trzeba, ale z niewłaściwych powodów. Kiedy zaczniesz naprawiać część programu, rzeczy często będą się pogarszać, dopóki nie naprawisz wszystkich programu.
"Dlaczego to nie działa?" To * działa *, ale to było moje doświadczenie z Unicode, że istnieje wiele bardzo zepsutych programów, które * wyglądają tak, jakby działały. Kiedy naprawisz jedną rzecz, czyniąc kod nieco mniej błędnym, wyniki wydają się dużo gorsze. Dopiero po naprawieniu * ostatniej * części wszystko wygląda dobrze. – hobbs
Zwykle naprawiane przez ustawienie wyjściowego uchwytu na 'binmode' z odpowiednim kodowaniem ... http://albertech.blogspot.com/2017/04/fix-annoying-wide-character-in-print.html – jar