Nachdem ein Artikel hier - nach mehreren Stunden vergeblichem herumraten - dafür gesorgt hat, dass ich die Lösung für ein Problem fand, gibt es hier vielleicht auch jemanden, der sie mir erklären kann. Ausgangspunkt war das Skript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
use utf8;
use Encode;
use Encode::Byte;
binmode(STDOUT, ":utf8");
sub do_it {
my $from = $_[0];
my $name = undef();
if ($from =~ m/^(.*?) </) {
print unpack('U0H*', $1) . "\n\n";
$name = substr($1, 0, 128);
print unpack('U0H*', $name) . "\n\n";
}
return;
}
my $from = 'AAçAA AñAA <a@b>';
$from = decode_utf8($from);
do_it($from);
print "--------------------------------------\n";
$from = 'AüAAA AA <a@b>';
$from = decode_utf8($from);
do_it($from);
In der letzten Ausgabe ist (jedenfalls hier und mit Perl 5.10.1) ein Null-Byte am Ende des Strings enthalten, welches dort einfach nicht hingehört. Ändert man die Eingangsdaten (z.B. durch Weglassen des ersten Buchstabens beim
ersten Aufruf), so verschwindet der Effekt. Das war nicht sehr erfreulich...
Nachdem ich irgendwann die Unicode-Verarbeitung von Perl verstanden hatte, aber immer noch ratlos war, bin ich hier vorbeigekommen und irgendwo über Devel::Peek gestolpert. Ersetzen der unpack-Befehle durch Dump brachte mich dann auf die Idee, testhalber
if (m =~ /.../) {
$name = substr($1, 0, 128);
}
durch
if (m =~ /.../) {
my $temp = $1;
$name = substr($temp, 0, 128);
}
zu ersetzen (weil dump($1) irgendwie seltsam und nicht so recht wie die anderen Strings aussah). Lustigerweise war dadurch mein Problem behoben... bloss will ich immer noch nicht so recht einsehen, dass mein ursprünglicher Code falsch war. Kann mir jemand hier erklären, welchen Fehler ich gemacht habe? Im Manual steht jedenfalls
QuoteThe numbered match variables ($1, $2, $3, etc.) and the related punctuation set ($+, $&, "$`", "$'", and $^N) are all dynamically scoped until the end of the enclosing block or until the next successful match, whichever comes first.
Last edited: 2012-08-13 08:02:11 +0200 (CEST)