Jeśli uruchomię następujący program w Perlu:
perl -e 'use utf8; print "鸡\n";'
Otrzymuję to ostrzeżenie:
Wide character in print at -e line 1.
Jeśli uruchomię ten program w Perlu:
perl -e 'print "鸡\n";'
Nie dostaję ostrzeżenia.
Pomyślałem, że use utf8
konieczne jest użycie znaków UTF-8 w skrypcie Perla. Dlaczego to nie działa i jak mogę to naprawić? Używam Perla 5.16.2. Mam ten sam problem, jeśli jest to w pliku zamiast być pojedynczą linijką w wierszu poleceń.
Odpowiedzi:
Bez
use utf8
Perla interpretuje twój ciąg jako sekwencję znaków jednobajtowych. Twój ciąg zawiera cztery bajty, jak widać z tego:$ perl -E 'say join ":", map { ord } split //, "鸡\n";' 233:184:161:10
Pierwsze trzy bajty tworzą twoją postać, ostatni to przesunięcie o linię.
Wywołanie
print
wysyła te cztery znaki do STDOUT. Twoja konsola ustali, jak wyświetlić te znaki. Jeśli twoja konsola jest ustawiona na używanie UTF8, to zinterpretuje te trzy bajty jako twój pojedynczy znak i to jest to, co jest wyświetlane.Jeśli dodamy do
utf8
modułu, sprawy mają się inaczej. W tym 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 pracuje ze znakami jednobajtowymi. Więc kiedy próbujesz wydrukować znak wielobajtowy, Perl myśli, że coś jest nie tak i wyświetla ostrzeżenie. Jak zawsze, możesz uzyskać więcej wyjaśnienia tego błędu, dołączając
use diagnostics
. Powie to:Jak zauważyli inni, musisz powiedzieć Perlowi, aby akceptował wielobajtowe wyjście. Można to zrobić na wiele sposobów ( kilka przykładów można znaleźć w samouczku Perl Unicode ). Jednym z najprostszych sposobów jest użycie
-CS
flagi wiersza poleceń - która mówi trzem standardowym uchwytom plików (STDIN, STDOUT i STDERR), aby poradziły sobie z UTF8.$ perl -Mutf8 -e 'print "鸡\n";' Wide character in print at -e line 1. 鸡
vs
$ perl -Mutf8 -CS -e 'print "鸡\n";' 鸡
Unicode to duży i złożony obszar. Jak widzieliście, wiele prostych programów wydaje się działać właściwie, ale z niewłaściwych powodów. Kiedy zaczynasz naprawiać część programu, sytuacja często się pogarsza, dopóki nie naprawisz całego programu.
źródło
-Mutf8
jeśli nie w jednym liniowcu perl?use utf8;
Wystarczy
use utf8;
powiedzieć Perlowi, że kod źródłowy jest zakodowany przy użyciu UTF-8. Musisz powiedzieć Perlowi, jak zakodować twój tekst:use open ':std', ':encoding(UTF-8)';
źródło
Zakoduj wszystkie standardowe wyjścia jako UTF-8:
binmode STDOUT, ":utf8";
źródło
use open ':std', ':encoding(UTF-8)';
zgodnie z propozycją innej odpowiedzi robi to dla STDOUT, ale również oznacza STDERR i STDIN jako UTF-8, więc otrzymujesz trzy za cenę jednego oświadczenia. Zobacz także stackoverflow.com/a/42194059Możesz zbliżyć się do "po prostu wykonaj utf8 wszędzie" za pomocą modułu CPAN
utf8::all
.perl -Mutf8::all -e 'print "鸡\n";'
Kiedy
print
otrzyma coś, czego nie może wydrukować (znak większy niż 255, gdy nie ma:encoding
warstwy), zakłada, że zamierzałeś zakodować to za pomocą UTF-8. Robi to po ostrzeżeniu o problemie.źródło
Możesz tego użyć,
To również zakończy ten błąd.
źródło
W języku hiszpańskim możesz znaleźć ten błąd, gdy obok zaczniesz używać:
use utf8;
Twoje kodowanie edytora jest w innym kodowaniu. Więc to, co widzisz w edytorze, nie jest tym, co robi Perl. Aby rozwiązać ten błąd, po prostu zmień kodowanie edytora na Unicode / UTF-8 .
źródło