Wie werden Zeichenketten in Perl intern dargestellt? Welche Kodierung wird verwendet? Wie gehe ich mit verschiedenen Kodierungen richtig um?
Ich benutze Perl schon seit langer Zeit, aber es enthielt nicht viele Möglichkeiten zur Behandlung von Zeichenketten in verschiedenen Kodierungen, und wenn ich auf ein kleines Problem stieß, das etwas mit Kodierungen zu tun hatte, griff ich gewöhnlich auf einige schamanische Aktionen zurück.
Bis zu diesem Zeitpunkt dachte ich an Perl-Strings als Sequenzen von Bytes, was für meine Aufgaben ziemlich gut passte. Jetzt muss ich eine UTF-8 kodierte Datei verarbeiten und hier beginnen die Probleme.
Zuerst lese ich die Datei wie folgt in einen String ein:
open(my $in, '<', $ARGV[0]) or die "cannot open file $ARGV[0] for reading";
binmode($in, ':utf8');
my $contents;
{
local $/;
$contents = <$in>;
}
close($in);
dann drucken Sie es einfach aus:
print $contents;
Und ich bekomme zwei Dinge: eine Warnung Wide character in print at <scriptname> line <n>
und eine Müllkonsole. Daraus kann ich schließen, dass Perl-Strings ein Konzept von "Zeichen" haben, das "breit" sein kann oder nicht, aber wenn sie gedruckt werden, werden diese "breiten" Zeichen in der Konsole als mehrere Bytes dargestellt, nicht als einzelnes "Zeichen". (Ich frage mich jetzt, warum alle meine früheren Erfahrungen mit Binärdateien so funktioniert haben, wie ich es erwartet hatte, ohne irgendwelche "Zeichen"-Probleme).
Warum sehe ich dann Müll in der Konsole? Wenn Perl Strings als Zeichen in einer bekannten Kodierung speichert, glaube ich nicht, dass es ein großes Problem ist, die Konsolenkodierung herauszufinden und den Text richtig zu drucken. (Ich benutze Windows, BTW).
Wenn Perl Zeichenketten als Zeichensequenzen mit variabler Breite speichert (z. B. unter Verwendung der gleichen UTF-8-Kodierung), warum geschieht das auf diese Weise? Nach meiner Erfahrung mit C ist der Umgang mit Zeichenketten eine Qual.
アップデート .
Ich verwende zwei Computer zum Testen, auf einem läuft Windows 7 x64 mit installiertem englischem Sprachpaket, aber mit russischen Regionaleinstellungen (ich habe also cp866 als OEM-Codepage und cp1251 als ANSI) mit ActivePerl 5.10.1 x64; auf dem anderen läuft Windows XP 32 Bit russische Lokalisierung mit Cygwin Perl 5.10.0.
Dank der Links habe ich jetzt ein viel besseres Verständnis dafür, was vor sich geht und wie die Dinge gehandhabt werden sollten.