Wenn Sie nicht use utf8;
haben, aber Sie den Code mit einem utf8 Texteditor anzeigen, sehen Sie es nicht so, wie Perl es sieht. Sie denken, Sie haben ein einzelnes Zeichen in der linken Hälfte Ihrer s///
und tr///
, aber weil es mehrere Bytes ist, sieht Perl es als mehrere Zeichen.
Was denken Sie Perl sieht:
my $str1 = "\xE8\xEE\xFC";
my $str2 = $str1;
$str1 =~ tr/\xEE/i/;
print "$str1\n";
$str2 =~ s/\xEE/i/;
print "$str2\n";
Welche Perl sieht tatsächlich:
my $str1 = "\xC3\xA8\xC3\xAE\xC3\xBC";
my $str2 = $str1;
$str1 =~ tr/\xC3\xAE/i/;
print "$str1\n";
$str2 =~ s/\xC3\xAE/i/;
print "$str2\n";
Mit s///
, da keiner der Charaktere regexp Operatoren sind, sind Sie nur eine Teil-Suche. Sie suchen nach einer Zeichenkette mit mehreren Zeichen. Und Sie finden es, weil das gleiche, was in Ihrem s///
passiert, auch in Ihren String-Literalen passiert: die Zeichen, die Sie denken, sind wirklich nicht, aber die Multi-Zeichen-Sequenz ist.
In tr///
auf der anderen Seite werden mehrere Zeichen nicht als eine Sequenz behandelt, sie werden als eine Menge behandelt. Jedes Zeichen (Byte) wird separat behandelt, wenn es gefunden wird. Und das bringt nicht die gewünschten Ergebnisse, weil das Ändern der einzelnen Bytes einer utf8-Zeichenfolge nie das ist, was Sie wollen.
Die Tatsache, dass Sie einfache ASCII-orientierte Teilstringsuche ausführen können, die nichts über utf8 wissen und das richtige Ergebnis für eine utf8-Zeichenfolge erhalten, wird im Gegensatz zu anderen Codierungen wie ucs2 als ein gutes Abwärtskompatibilitätsmerkmal von utf8 betrachtet/utf16 oder ucs4.
Die Lösung ist, die Quelle zu sagen, Perl ist durch Hinzufügen von use utf8;
UTF-8 codiert werden. Sie müssen auch Ihre Ausgaben codieren, damit sie mit dem übereinstimmen, was Ihr Terminal erwartet.
use utf8; # The source is encoded using UTF-8.
use open ':std', ':encoding(UTF-8)'; # The terminal provides/expects UTF-8.
my $str1 = 'èîü';
my $str2 = $str1;
$str1 =~ tr/î/i/;
print "$str1\n";
$str2 =~ s/î/i/;
print "$str2\n";
Es funktioniert auch für mich, danke. Irgendeine Idee, warum 'tr' scheint, diese Pragmas zu brauchen, während's' nicht? – Georg
Ich wollte nur etwas über die Semantik von Zeichenketten und Bytestrings sagen, aber siehe @ Wumpus 'Antwort, ich denke, es erklärt das Problem viel besser. – zoul
@ zoul, ich bin froh, dass du es nicht getan hast; Dies hat nichts mit den beiden internen Speicherformaten zu tun. – ikegami