[Regex] Suchen nach Hex-Zeichen

[Regex] Suchen nach Hex-Zeichen

am 18.06.2006 08:32:32 von Til Schubbe

Hallo,

wenn ich nach einer längeren Hex-Zeichenkette suchen möchte, kann ich
laut "Programmieren mit Perl" die Notation \x{HH} benutzen, wobei HH
eine beliebige Anzahl von Hex-Zeichen sein kann.

Bei folgendem Programm funktioniert das aber nicht:

----8<----
#!/usr/bin/perl

use warnings;

$t = " \x26\x2f ";
$t1 = $t;
&hexprint;

$t1 = $t;
$t1 =~ s/\x26\x2f//;
&hexprint;

$t1 = $t;
$t1 =~ s/\x{262f}//;
&hexprint;

sub hexprint {
for $i (0..(length $t1) -1) {
printf "%2x", ord (substr ($t1, $i, 1));
}
print "\n";
}
---->8----

Ich erhalte:
20262f20
2020
20262f20

Das Pattern '\x26\x2f' matched, '\x{262f}' aber nicht. Warum?

TIA + Gruß
Til

Re: [Regex] Suchen nach Hex-Zeichen

am 18.06.2006 10:19:32 von Slaven Rezic

Til Schubbe writes:

> Hallo,
>
> wenn ich nach einer längeren Hex-Zeichenkette suchen möchte, kann ich
> laut "Programmieren mit Perl" die Notation \x{HH} benutzen, wobei HH
> eine beliebige Anzahl von Hex-Zeichen sein kann.
>
> Bei folgendem Programm funktioniert das aber nicht:
>
[...]
>
> Das Pattern '\x26\x2f' matched, '\x{262f}' aber nicht. Warum?
>

Mit \x{....} sprichst du einen Unicode-Codepoint an. Bei \x{262f} ist
es das YIN YANG-Symbol.

Gruß,
Slaven

Re: [Regex] Suchen nach Hex-Zeichen

am 18.06.2006 10:33:55 von news.5.maazl

Hi,

Til Schubbe schrieb:
> wenn ich nach einer längeren Hex-Zeichenkette suchen möchte, kann ich
> laut "Programmieren mit Perl" die Notation \x{HH} benutzen, wobei HH
> eine beliebige Anzahl von Hex-Zeichen sein kann.

Die \x{HH} Notation ist nur eine andere Art, einen String anzugeben. Die
Regex-Metazeichen werden trotzdem interpretiert. Außerdem gibt \x{HHHH}
ein Unicode-Zeichen, und das ist bestimmt nicht das Ziel der Aktion.

Also wenn, dann bitte so:

> Bei folgendem Programm funktioniert das aber nicht:
>
> ----8<----
> #!/usr/bin/perl
>
> use warnings;
>
> $t = " \x26\x2f ";
> $t1 = $t;
> &hexprint;
>
> $t1 = $t;
> $t1 =~ s/\x26\x2f//;
besser:
$find = quotemeta "\x26\x2f";
$t1 =~ s/$find//;
Denn schon bei \x27 geht es sonst in die Hose.
> &hexprint;
>
> $t1 = $t;
> $t1 =~ s/\x{262f}//;
Kein Unicode versuchen!
$find = quotemeta "\x{26}\x{2f}";
$t1 =~ s/$find//;
> &hexprint;

.... dann klappt's auch mit dem Nachbarn.


Marcel

Re: [Regex] Suchen nach Hex-Zeichen

am 18.06.2006 12:13:55 von hjp-usenet2

Til Schubbe wrote:
> wenn ich nach einer längeren Hex-Zeichenkette suchen möchte, kann ich
> laut "Programmieren mit Perl" die Notation \x{HH} benutzen, wobei HH
> eine beliebige Anzahl von Hex-Zeichen sein kann.
>
[...]
>
> Das Pattern '\x26\x2f' matched, '\x{262f}' aber nicht. Warum?

Weil "\x{262f}" *ein* Zeichen mit dem Code 0x262f ist, nicht zwei
Zeichen mit den Codes 0x26 0x2f.

Probier mal:

#!/usr/bin/perl
use warnings;
use strict;

my $x = "\x{262f}";
my $y = "\x{26}\x{2f}";

print "len(x)=", length($x), ", ord(x)=", ord($x), "\n";
print "len(y)=", length($y), ", ord(y)=", ord($y), "\n";
print (($x eq $y ? "equal" : "not equal"), "\n");

hp

--
_ | Peter J. Holzer | Man könnte sich [die Diskussion] auch
|_|_) | Sysadmin WSR/LUGA | sparen, wenn man sie sich einfach sparen
| | | hjp@hjp.at | würde.
__/ | http://www.hjp.at/ | -- Ralph Angenendt in dang 2006-04-15

Re: [Regex] Suchen nach Hex-Zeichen

am 18.06.2006 12:34:06 von Til Schubbe

Hi,

Marcel Müller meinte:

> Außerdem gibt \x{HHHH}
> ein Unicode-Zeichen, und das ist bestimmt nicht das Ziel der Aktion.

Ja, stimmt. Eigentlich war's eine allgemeine Frage, wie man beliebig
lange Hex-Strings als Muster angeben kann.

Konkret möchte ich in einem String jedes Vorkommen von \x00\x00\x0a
löschen. Und da wäre \x{00000a} halt kürzer gewesen.

>> $t1 =~ s/\x26\x2f//;
> besser:
> $find = quotemeta "\x26\x2f";
> $t1 =~ s/$find//;
> Denn schon bei \x27 geht es sonst in die Hose.

Hm, warum?

Gruß
Til

Re: [Regex] Suchen nach Hex-Zeichen

am 18.06.2006 12:57:32 von Til Schubbe

Peter J. Holzer meinte:

>> Das Pattern '\x26\x2f' matched, '\x{262f}' aber nicht. Warum?
>
> Weil "\x{262f}" *ein* Zeichen mit dem Code 0x262f ist, nicht zwei
> Zeichen mit den Codes 0x26 0x2f.

Ah, ok. Das war mein Denkfehler.

> Probier mal:

> my $x = "\x{262f}";

[...]
len(x)=1, ord(x)=9775

Wie kommt man denn mit einem einzigen Byte aus? Existieren noch
irgendwo anders (Meta)-Informationen zu diesem String, die von length
nicht berücksichtigt werden?

Oder anders gefragt: Gibt es bei Unicode eine Art logische und eine
physikalische Länge? Oder Zeichensatzinformationen?

Gruß
Til

Re: [Regex] Suchen nach Hex-Zeichen

am 18.06.2006 20:34:51 von Slaven Rezic

Til Schubbe writes:

> Peter J. Holzer meinte:
>
> >> Das Pattern '\x26\x2f' matched, '\x{262f}' aber nicht. Warum?
> >
> > Weil "\x{262f}" *ein* Zeichen mit dem Code 0x262f ist, nicht zwei
> > Zeichen mit den Codes 0x26 0x2f.
>
> Ah, ok. Das war mein Denkfehler.
>
> > Probier mal:
>
> > my $x = "\x{262f}";
>
> [...]
> len(x)=1, ord(x)=9775
>
> Wie kommt man denn mit einem einzigen Byte aus? Existieren noch
> irgendwo anders (Meta)-Informationen zu diesem String, die von length
> nicht berücksichtigt werden?
>
> Oder anders gefragt: Gibt es bei Unicode eine Art logische und eine
> physikalische Länge? Oder Zeichensatzinformationen?

Bei Unicode gibt es zunächst nur Codepoints, oder anders ausgedrückt,
jedem Zeichen wird eine Zahl zugeordnet. Über das konkrete Encoding
ist damit erst einmal nichts gesagt. Wenn man die Zeichen dann für die
Maschinenhardware konkret ausdrücken will, kommen Encodings ins Spiel.
Ein populäres Encoding ist utf-8, mit dem Unicode-Zeichen mit einer
variablen Länge kodiert werden (obiges z.B. mit drei Zeichen). Es gibt
aber auch Encodings mit fixen Längen, wie z.B. UCS-2, wo es zwei Byte
wären oder UCS-4 mit vier Byte usw.

Gruß,
Slaven

--
Slaven Rezic - slaven rezic de

sf-upload: make batch releases on SourceForge
http://sf-upload.sf.net

Re: [Regex] Suchen nach Hex-Zeichen

am 18.06.2006 21:18:29 von hjp-usenet2

Til Schubbe wrote:
> Peter J. Holzer meinte:
>>> Das Pattern '\x26\x2f' matched, '\x{262f}' aber nicht. Warum?
>>
>> Weil "\x{262f}" *ein* Zeichen mit dem Code 0x262f ist, nicht zwei
>> Zeichen mit den Codes 0x26 0x2f.
>
> Ah, ok. Das war mein Denkfehler.
>
>> Probier mal:
>
>> my $x = "\x{262f}";
>
> [...]
> len(x)=1, ord(x)=9775
>
> Wie kommt man denn mit einem einzigen Byte aus?

Gar nicht. Ein String ist in Perl (seit Version 5.6) keine Folge von
Bytes, sondern eine Folge von 32-Bit-Werten.

> Existieren noch irgendwo anders (Meta)-Informationen zu diesem String,
> die von length nicht berücksichtigt werden?

Ja, einige. Ein Perl-Skalar ist ein relativ komplexes Ding. Eine recht
gute Übersicht ist auf http://gisle.aas.no/perl/illguts/ zu finden, aber
die ist etliche Jahre veraltet (von UTF-8 steht dort nichts). Aktuell
sollte jeweils perldoc perlguts sein.

> Oder anders gefragt: Gibt es bei Unicode eine Art logische und eine
> physikalische Länge?

Ja. Da ein Zeichen mehr als ein Byte benötigt (eh klar, wenn es mehrere
tausend Zeichen gibt) ist die physikalische Länge (in Bytes) meistens
länger als die logische Länge (in Zeichen). Wie lang genau, hängt von
der Kodierung und vom Inhalt ab. Perl verwendet intern entweder eine
einfache Byte-Kodierung (wenn alle Zeichen <= 0xFF) oder UTF-8. UTF-8
ist eine Kodierung mit variabler Länge: Codes von 0x0 bis 0x7F
werden als 1 Byte dargestellt, von 0x80 bis 0x1FFF als 2 Bytes, etc.

> Oder Zeichensatzinformationen?

Nein. Unicode ist ein Zeichensatz[0], nicht eine Sammlung von
Zeichensätzen.

hp

[0] Plus Etliches drumherum.

--
_ | Peter J. Holzer | Man könnte sich [die Diskussion] auch
|_|_) | Sysadmin WSR/LUGA | sparen, wenn man sie sich einfach sparen
| | | hjp@hjp.at | würde.
__/ | http://www.hjp.at/ | -- Ralph Angenendt in dang 2006-04-15

Re: [Regex] Suchen nach Hex-Zeichen

am 19.06.2006 10:42:57 von news.5.maazl

Hallo,

Til Schubbe schrieb:
>>>$t1 =~ s/\x26\x2f//;
>>
>>besser:
>> $find = quotemeta "\x26\x2f";
>> $t1 =~ s/$find//;
>>Denn schon bei \x27 geht es sonst in die Hose.
>
>
> Hm, warum?

Ja, sorry war ein Kalter. Direkt zwischen // werden die Hex-Codes immer
als Escapes gewertet, nur folgendes würde schief gehen, weil \x28 = (:

$find = "\x28\x2f";
$t1 =~ s/$find//;


Marcel

Re: [Regex] Suchen nach Hex-Zeichen

am 19.06.2006 10:53:17 von Ferry Bolhar

Peter J. Holzer:

> > Das Pattern '\x26\x2f' matched, '\x{262f}' aber nicht. Warum?
>
> Weil "\x{262f}" *ein* Zeichen mit dem Code 0x262f ist,

Wobei "Code" hier nichts mehr mit dem internen Speicherformat
zu tun hat - in UTF-8 wird es als e2-98-af (also in drei Bytes)
abgespeichert.

> Probier mal:

[...]

Und jetzt probier mal das Beispiel noch einmal mit:

use bytes;

am Anfang. Das wäre auch eine Möglichkeit zur Lösung gewesen -
es veranlasst Perl, im lexikalischen Bereich dieses Pragmas auch UTF-8
Sequenzen als einzelne Bytes zu betrachten (und auch in Regexes
entsprechend auszuwerten).

LG, Ferry

--
Ing. Ferry Bolhar
Municipality of Vienna, Department 14
A-1010 Vienna / AUSTRIA
E-mail: bol@adv.magwien.gv.at

Re: [Regex] Suchen nach Hex-Zeichen

am 19.06.2006 11:30:45 von Ferry Bolhar

Peter J. Holzer:

>> Wie kommt man denn mit einem einzigen Byte aus?
>
> Gar nicht. Ein String ist in Perl (seit Version 5.6) keine Folge von
> Bytes, sondern eine Folge von 32-Bit-Werten.

Hm... mal sehen:

use Devel::Peek;
Dump "Hello";

ergibt bei mir:

SV = PV(0x923d408) at 0x92235c8
REFCNT = 1
FLAGS = (PADBUSY,PADTMP,POK,READONLY,pPOK)
PV = 0x92239e0 "Hello"\0
CUR = 5
LEN = 6

Deine Definition eines Strings dürfte so nicht stimmen - Perl benötigt
zum Abspeichern von "Hello" genau 5 Bytes (plus Nullbyte). Oder ich
verstehe den Ausdruck "Folge von 32-Bit-Werten" falsch?

> > Existieren noch irgendwo anders (Meta)-Informationen zu diesem String,
> > die von length nicht berücksichtigt werden?
>
> Ja, einige.

Welche? Ich weiß nur vom UTF-8 Flag (siehe weiter unten).

> Ein Perl-Skalar ist ein relativ komplexes Ding. Eine recht
> gute Übersicht ist auf http://gisle.aas.no/perl/illguts/ zu finden, aber
> die ist etliche Jahre veraltet (von UTF-8 steht dort nichts).

UTF-8-Unterstützung in der jetzigen Form kam erst in Perl 5.8,
Gisle's Dokumentation stammt aus Perl 5.005 (teilweise noch
früher) Zeiten. Da war von UTF-8 noch keine Rede.

(BTW: weiß jemand von einer aktualisierten Form dieser Doku?
In der Version, die ich habe, sind noch viele Themen mit "Not Yet"
gekennzeichnet.)

Ein Skalar, der eine UTF-8-kodierte Zeichenkette enthält, hat
lediglich ein Flag (Svf_UTF8 in seinem SvFLAGS Feld) gesetzt.
Mehr ist da nicht dahinter.

>> Oder anders gefragt: Gibt es bei Unicode eine Art logische und eine
>> physikalische Länge?

Wie Slaven schon richtig geschrieben hat, muss man zwischen Unicode
und UTF-8 unterscheiden:

Unicode: jedes Zeichen hat eine eindeutige Nummer (zB. das hier
erwähnte Ying-Yang-Zeichen hex 262f). Unicode definiert also einen
Zeichensatz.

UTF-8: eine der vielen Möglichkeiten, Unicode-Zeichen zu kodieren.
UTF-8 verwendet ein Schema mit variabler Länge, wobei der Wert
des ersten Bytes bestimmt, wieviele Bytes folgen:

C4..DF 1 Byte
E0..EF 2 Byte
F0..F7 3 Byte
F8..FB 4 Bytes
FC.FD 5 Bytes

Die folgenden Bytes haben stets Werte zwischen 80 und BF, d.h.,
bei UTF-8-kodierterm Unicode ist stets das oberste Bit gesetzt.
Daher können die standard ASCII-Zeichen (00..7F) eins zu eins
übernommen werden, ein "!" wird in UTF-8 genauso als hex 21
abgespeichert wie in ASCII.

Perl weiß nichts über Unicode, es weiß aber genau, wie in UTF-8
kodiert wird. Gibt man also ein Zeichen in der Notation \x{aabb} an,
so nimmt Perl an (wenn der Wert größer als 255 ist und daher in einem
Byte nicht mehr abgespeichert werden kann), dass es in UTF-8 kodiert
werden soll. Das heißt, aus 'aabb' wird eine gültige UTF8-Sequenz
und im betreffenden Scalarwert (SV) wird das Svf_UTF8 Flag
gesetzt. Funktionen, die dann auf den Stringwert zugreifen, erkennen
anhand des gesetzen Flags, dass es sich um einen UTF-8-kodierten
Wert handelt und berücksichtigen dies entsprechend. Mehr steckt
da nicht dahinter.

Mit "use bytes" kann man veranlassen, dass innerhalb des aktuellen
lexikalischen Bereiches UTF-8 Flags ignoriert und UTF-8 Sequenzen
in Skalaren somit nicht mehr als solche behandelt werden:

$a = "\x{0100}"; # Kodiert als C4 80, UTF-8 Flag wird gesetzt
print length $a; # Liefert "1", da ein _logisches_ Zeichen
{
use bytes; # Ignoriere UTF-8 Flags
print length $a; # Liefert "2", da zwei _physische_ Zeichen
}

LG, Ferry

--
Ing. Ferry Bolhar
Municipality of Vienna, Department 14
A-1010 Vienna / AUSTRIA
E-mail: bol@adv.magwien.gv.at

Re: [Regex] Suchen nach Hex-Zeichen

am 19.06.2006 16:10:31 von hjp-usenet2

Ferry Bolhar wrote:
> Peter J. Holzer:
>>> Wie kommt man denn mit einem einzigen Byte aus?
>>
>> Gar nicht. Ein String ist in Perl (seit Version 5.6) keine Folge von
>> Bytes, sondern eine Folge von 32-Bit-Werten.
[...]
> Deine Definition eines Strings dürfte so nicht stimmen - Perl benötigt
> zum Abspeichern von "Hello" genau 5 Bytes (plus Nullbyte). Oder ich
> verstehe den Ausdruck "Folge von 32-Bit-Werten" falsch?

Ja. Ich meinte, dass es *logisch* eine Folge von 32-Bit-Werten ist:
ord($string) kann Werte von 0 .. 2**32-1 (oder war das 2**31-1?)
liefern, chr($n) akzeptiert die gleichen Zahlenbereich, ebenso wie
\x{...}.

*Gespeichert* werden sie - wie ich geschrieben habe (sogar zweimal) -
nicht als Folge von 32-Bit-Worten, sondern entweder als Bytes oder in
UTF-8-Kodierung. Aber das ist ein Implementationsdetail, das den
Perl-Programmierer eigentlich nicht kümmern muss - das ist eigentlich
nur wichtig, wenn man auf die Interna zugreifen muss (z.B. bei der
XS-Programmierung) und prinzipiell könnte sich das auch jederzeit ändern
(insofern halte ich Funktionsnamen wie "is_utf8" für unglücklich - das
sollte eher "is_wide" heißen).


>> > Existieren noch irgendwo anders (Meta)-Informationen zu diesem String,
>> > die von length nicht berücksichtigt werden?
>>
>> Ja, einige.
>
> Welche? Ich weiß nur vom UTF-8 Flag (siehe weiter unten).

Der ganze Rest vom SV. Das sind alles Meta-Informationen, die von
Length nicht berücksichtigt werden. Nein, mit UTF-8 haben sie nichts zu
tun, aber das war ja auch nicht gefragt.

> Perl weiß nichts über Unicode,

Das ist nicht richtig. Perl weiß sehr wohl einiges über Unicode, z.b.
kennt es die Properties:

#!/usr/bin/perl
use warnings;
use strict;
use utf8;

for ("ein Ast",
"zwei Äste",
"1 \x{0391}\x{03BB}\x{03C6}\x{03B1}",
"kein €uro") {
if (/(\p{Lu})/) {
print "$1\n";
} else {
print "no match\n";
}
}

gibt

A
Ä
Α
no match

aus.

hp

--
_ | Peter J. Holzer | Man könnte sich [die Diskussion] auch
|_|_) | Sysadmin WSR/LUGA | sparen, wenn man sie sich einfach sparen
| | | hjp@hjp.at | würde.
__/ | http://www.hjp.at/ | -- Ralph Angenendt in dang 2006-04-15

Re: [Regex] Suchen nach Hex-Zeichen

am 19.06.2006 19:05:27 von Ferry Bolhar

Peter J. Holzer:

>> Deine Definition eines Strings dürfte so nicht stimmen - Perl benötigt
>> zum Abspeichern von "Hello" genau 5 Bytes (plus Nullbyte). Oder ich
>> verstehe den Ausdruck "Folge von 32-Bit-Werten" falsch?
>
> Ja. Ich meinte, dass es *logisch* eine Folge von 32-Bit-Werten ist:
> ord($string) kann Werte von 0 .. 2**32-1 (oder war das 2**31-1?)
> liefern, chr($n) akzeptiert die gleichen Zahlenbereich, ebenso wie
> \x{...}.

Du denkst (für mich) etwas zu abstrakt, das ist für mich nicht nachvoll-
ziehbar - Tatsache ist, dass auch in Perl 5.8.8 der String "Hello" in 5 + 1
Byte abgespeichert wird, und zwar genauso wie in 5.6.x und 5.005_x
(ältere Versionen habe ich nicht bei der Hand, es wird aber dort kaum
anders gewesen sein). Was willst du also mit

>> Ein String ist in Perl (seit Version 5.6) keine Folge von
>> Bytes, sondern eine Folge von 32-Bit-Werten

sagen? Was ist an einem String seit 5.6 anders?

> *Gespeichert* werden sie - wie ich geschrieben habe (sogar zweimal) -
> nicht als Folge von 32-Bit-Worten, sondern entweder als Bytes oder in
> UTF-8-Kodierung. Aber das ist ein Implementationsdetail, das den
> Perl-Programmierer eigentlich nicht kümmern muss - das ist eigentlich
> nur wichtig, wenn man auf die Interna zugreifen muss (z.B. bei der
> XS-Programmierung) und prinzipiell könnte sich das auch jederzeit ändern
> (insofern halte ich Funktionsnamen wie "is_utf8" für unglücklich - das
> sollte eher "is_wide" heißen).

Da sich die Perl-Entwicklergemeinde auf UTF-8 zur Unicode-Codierung
eingeschworen hat, glaube ich nicht, dass sich das noch ändern wird,
denn das würde bedeuten, dass mit 5.8 weggeschriebener Unicode mit
künftigen Versionen nicht mehr (oder nur mit Zubauten) lesbar wäre.
Außerdem könnte man dann sämtlichen auf UTF-8 basierenden XS-
Code kübeln.

> > Welche? Ich weiß nur vom UTF-8 Flag (siehe weiter unten).
>
> Der ganze Rest vom SV. Das sind alles Meta-Informationen, die von
> Length nicht berücksichtigt werden. Nein, mit UTF-8 haben sie nichts zu
> tun, aber das war ja auch nicht gefragt.

Hm... lass sehen:

use Deve::Peek;
$a = "\x{0100}";
Dump $a;

ergibt:

SV = PV(0x9bfaef8) at 0x9c0e150
REFCNT = 1
FLAGS = (POK,pPOK,UTF8)
PV = 0x9c0ad58 "\304\200"\0 [UTF8 "\x{100}"]
CUR = 2
LEN = 3

Das Unicode-Zeichen hex 100 wird in UTF-8 als C4-80 (oder
eben oktal 304-200) abgelegt, benötigt somit 2 + 1 Abschlussbyte.
Das UTF8 Flag ist gesetzt, aber davon abgesehen ist das ein
vollkommen normaler PV, wie jeder andere String auch. Wo sind
deine Meta-Informationen? Wo ist "der ganze Rest vom SV"?

> Das ist nicht richtig. Perl weiß sehr wohl einiges über Unicode, z.b.
> kennt es die Properties:

OK, jetzt hast mich erwischt ;-) Ich hätte sagen sollen, "der Perl
Core weiß nichts darüber". Die Unicode-Properties sind durch das
"utf8" Pragma und seine Subdateien implementiert, das der Core
übrigens selbst lädt, wenn er es benötigt.

Dein Beispiel gibt übrigens (zumindest bei mir) die Fehler:

Malformed UTF-8 character (unexpected non-continuation byte 0x73,
immediately af
ter start byte 0xc4) at z.pl line 6.
Malformed UTF-8 character (unexpected continuation byte 0x80, with no
preceding
start byte) at z.pl line 8.

aus. Ist das bei dir auch so?

Schöne Grüße aus Wien,

Ferry

--
Ing. Ferry Bolhar
Municipality of Vienna, Department 14
A-1010 Vienna / AUSTRIA
E-mail: bol@adv.magwien.gv.at

Re: [Regex] Suchen nach Hex-Zeichen

am 19.06.2006 19:26:37 von Slaven Rezic

"Ferry Bolhar" writes:

> Peter J. Holzer:
>
> >> Deine Definition eines Strings dürfte so nicht stimmen - Perl benötigt
> >> zum Abspeichern von "Hello" genau 5 Bytes (plus Nullbyte). Oder ich
> >> verstehe den Ausdruck "Folge von 32-Bit-Werten" falsch?
> >
> > Ja. Ich meinte, dass es *logisch* eine Folge von 32-Bit-Werten ist:
> > ord($string) kann Werte von 0 .. 2**32-1 (oder war das 2**31-1?)
> > liefern, chr($n) akzeptiert die gleichen Zahlenbereich, ebenso wie
> > \x{...}.
>
> Du denkst (für mich) etwas zu abstrakt, das ist für mich nicht nachvoll-
> ziehbar - Tatsache ist, dass auch in Perl 5.8.8 der String "Hello" in 5 + 1
> Byte abgespeichert wird, und zwar genauso wie in 5.6.x und 5.005_x
> (ältere Versionen habe ich nicht bei der Hand, es wird aber dort kaum
> anders gewesen sein). Was willst du also mit
>
> >> Ein String ist in Perl (seit Version 5.6) keine Folge von
> >> Bytes, sondern eine Folge von 32-Bit-Werten
>
> sagen? Was ist an einem String seit 5.6 anders?

"32-Bit-Werte" finde ich auch nicht so glücklich gewählt --- ich würde
lieber einfach nur "Integer" oder "Zahl" sagen. In den Perl-Interna
ist schon alles dafür vorbereitet auch mit größen Zahlen als
32-Bit-Werten für die Unicode-Repräsentation arbeiten zu können.

>
> > *Gespeichert* werden sie - wie ich geschrieben habe (sogar zweimal) -
> > nicht als Folge von 32-Bit-Worten, sondern entweder als Bytes oder in
> > UTF-8-Kodierung. Aber das ist ein Implementationsdetail, das den
> > Perl-Programmierer eigentlich nicht kümmern muss - das ist eigentlich
> > nur wichtig, wenn man auf die Interna zugreifen muss (z.B. bei der
> > XS-Programmierung) und prinzipiell könnte sich das auch jederzeit ändern
> > (insofern halte ich Funktionsnamen wie "is_utf8" für unglücklich - das
> > sollte eher "is_wide" heißen).
>
> Da sich die Perl-Entwicklergemeinde auf UTF-8 zur Unicode-Codierung
> eingeschworen hat, glaube ich nicht, dass sich das noch ändern wird,
> denn das würde bedeuten, dass mit 5.8 weggeschriebener Unicode mit
> künftigen Versionen nicht mehr (oder nur mit Zubauten) lesbar wäre.
> Außerdem könnte man dann sämtlichen auf UTF-8 basierenden XS-
> Code kübeln.

Die intere Repräsentation hat nichts mit dem zu tun, was man wirklich
per I/O oder sonstwie ausgibt. Bei der Kommunikation mit der Außenwelt
muss man das Encoding angeben, und da gibt es UTF-8, aber auch UCS-2,
UCS-4, ISO-8859-1 usw. Bei der Ausgabe sind alle Encodings mehr oder
weniger gleichberechtigt.

Gruß,
Slaven

--
Slaven Rezic - slaven rezic de

Tk-AppMaster: a perl/Tk module launcher designed for handhelds
http://tk-appmaster.sf.net

Re: [Regex] Suchen nach Hex-Zeichen

am 19.06.2006 21:15:05 von Frank Seitz

Slaven Rezic wrote:
> "Ferry Bolhar" writes:
>>Peter J. Holzer:
>>>
>>>Ja. Ich meinte, dass es *logisch* eine Folge von 32-Bit-Werten ist:
>>>ord($string) kann Werte von 0 .. 2**32-1 (oder war das 2**31-1?)
>>>liefern, chr($n) akzeptiert die gleichen Zahlenbereich, ebenso wie
>>>\x{...}.
>>
>>Du denkst (für mich) etwas zu abstrakt, das ist für mich nicht nachvoll-
>>ziehbar - Tatsache ist, dass auch in Perl 5.8.8 der String "Hello" in 5 + 1
>>Byte abgespeichert wird, und zwar genauso wie in 5.6.x und 5.005_x
>>(ältere Versionen habe ich nicht bei der Hand, es wird aber dort kaum
>>anders gewesen sein). Was willst du also mit
>>
>>>>Ein String ist in Perl (seit Version 5.6) keine Folge von
>>>>Bytes, sondern eine Folge von 32-Bit-Werten
>>
>>sagen? Was ist an einem String seit 5.6 anders?
>
> "32-Bit-Werte" finde ich auch nicht so glücklich gewählt --- ich würde
> lieber einfach nur "Integer" oder "Zahl" sagen. In den Perl-Interna
> ist schon alles dafür vorbereitet auch mit größen Zahlen als
> 32-Bit-Werten für die Unicode-Repräsentation arbeiten zu können.

Hm, für mich ist ein String *logisch* immer noch eine Folge von Zeichen,
nicht von Zahlen oder gar 32-Bit-Werten. Mathematisch gesprochen
definiert ord() eine Abbildung von der Menge der Zeichen in die
Menge der natürlichen Zahlen. Gerade wenn man genau sein will,
sollte man das m.E. nicht miteinander identifizieren.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: [Regex] Suchen nach Hex-Zeichen

am 20.06.2006 00:24:30 von hjp-usenet2

Ferry Bolhar wrote:
> Peter J. Holzer:
>>> Deine Definition eines Strings dürfte so nicht stimmen - Perl benötigt
>>> zum Abspeichern von "Hello" genau 5 Bytes (plus Nullbyte). Oder ich
>>> verstehe den Ausdruck "Folge von 32-Bit-Werten" falsch?
>>
>> Ja. Ich meinte, dass es *logisch* eine Folge von 32-Bit-Werten ist:
>> ord($string) kann Werte von 0 .. 2**32-1 (oder war das 2**31-1?)
>> liefern, chr($n) akzeptiert die gleichen Zahlenbereich, ebenso wie
>> \x{...}.
>
> Du denkst (für mich) etwas zu abstrakt, das ist für mich nicht nachvoll-
> ziehbar

Das gewöhnt man sich als C-Programmierer recht schnell an, wenn man für
so verschiedene Plattformen wie 8086, diverse RISC-Prozessoren und DSPs
programmiert und nebenbei noch in comp.std.c diskutiert. Wenn man da
nicht lernt, die abstrakte Programmiersprache von der konkreten
Implementation zu trennen, steht man auf verlorenem Posten. Das ist zwar
schon eine Weile her, und von Perl gibt es nur eine Implementation, aber
die Angewohnheit, verschiedene Abstraktionsebenen zu trennen, habe ich
nicht aufgegeben. Die ist nämlich beim Problemlösen im Allgemeinen (und
beim Programmieren im Speziellen) recht hilfreich.

> - Tatsache ist, dass auch in Perl 5.8.8 der String "Hello" in 5 + 1
> Byte abgespeichert wird, und zwar genauso wie in 5.6.x und 5.005_x
> (ältere Versionen habe ich nicht bei der Hand, es wird aber dort kaum
> anders gewesen sein). Was willst du also mit
>
>>> Ein String ist in Perl (seit Version 5.6) keine Folge von
>>> Bytes, sondern eine Folge von 32-Bit-Werten
>
> sagen? Was ist an einem String seit 5.6 anders?

Anders ist, dass Du seit 5.6 (theoretisch) bzw. 5.8 (praktisch) eben
sowas wie

$x = chr(1234) . chr(5678);

schreiben kannst und dann tatsächlich einen String der Länge zwei hast,
wobei ord(substr($x, 0)) == 1234 und ord(substr($x, 1)) == 5678 ist.

Bis inklusive 5.005 war man da auf Werte von 0..255 eingeschränkt.

>> *Gespeichert* werden sie - wie ich geschrieben habe (sogar zweimal) -
>> nicht als Folge von 32-Bit-Worten, sondern entweder als Bytes oder in
>> UTF-8-Kodierung. Aber das ist ein Implementationsdetail, das den
>> Perl-Programmierer eigentlich nicht kümmern muss - das ist eigentlich
>> nur wichtig, wenn man auf die Interna zugreifen muss (z.B. bei der
>> XS-Programmierung) und prinzipiell könnte sich das auch jederzeit ändern
>> (insofern halte ich Funktionsnamen wie "is_utf8" für unglücklich - das
>> sollte eher "is_wide" heißen).
>
> Da sich die Perl-Entwicklergemeinde auf UTF-8 zur Unicode-Codierung
> eingeschworen hat, glaube ich nicht, dass sich das noch ändern wird,

Wenn sie - wie Slaven schreibt - den Wertebereich von 32 auf 64 Bit
erweitern wollen, werden sie müssen. UTF-8 kann nur 36 Bit abdecken.

> denn das würde bedeuten, dass mit 5.8 weggeschriebener Unicode mit
> künftigen Versionen nicht mehr (oder nur mit Zubauten) lesbar wäre.

Nein, überhaupt nicht. Die interne Repräsentation ist für Perl-Programme
völlig egal.

> Außerdem könnte man dann sämtlichen auf UTF-8 basierenden XS-
> Code kübeln.

Das allerdings. Oder irgendeinen Compatibilitätshack einfügen. Oder eine
dritte Repräsentation.



>> Der ganze Rest vom SV. Das sind alles Meta-Informationen, die von
>> Length nicht berücksichtigt werden. Nein, mit UTF-8 haben sie nichts zu
>> tun, aber das war ja auch nicht gefragt.
>
> Hm... lass sehen:
>
> use Deve::Peek;
> $a = "\x{0100}";
> Dump $a;
>
> ergibt:
>
> SV = PV(0x9bfaef8) at 0x9c0e150
> REFCNT = 1
> FLAGS = (POK,pPOK,UTF8)
> PV = 0x9c0ad58 "\304\200"\0 [UTF8 "\x{100}"]
> CUR = 2
> LEN = 3

Genau die Felder, die Du da auflistest: Das sind typischerweise schon
6*4=24 Bytes, die bei jedem Scalar, der ein String ist, dabei sind, aber
nicht zur Länge dazugezählt werden. Wenn der String einen numerischen
Wert hat, kommen u.U. noch 4 und/oder 8 Bytes für den Integer bzw.
Floatingpoint-Wert dazu.


> Das Unicode-Zeichen hex 100 wird in UTF-8 als C4-80 (oder
> eben oktal 304-200) abgelegt, benötigt somit 2 + 1 Abschlussbyte.
> Das UTF8 Flag ist gesetzt, aber davon abgesehen ist das ein
> vollkommen normaler PV, wie jeder andere String auch.

Eben. Wie jeder andere String auch. Warum sollte ein UTF-8-String den
ganzen Overhead, den ein "normaler" String hat, nicht haben?

> Wo sind deine Meta-Informationen?

Im SV bzw. xpv.

>> Das ist nicht richtig. Perl weiß sehr wohl einiges über Unicode, z.b.
>> kennt es die Properties:
>
> OK, jetzt hast mich erwischt ;-) Ich hätte sagen sollen, "der Perl
> Core weiß nichts darüber". Die Unicode-Properties sind durch das
> "utf8" Pragma und seine Subdateien implementiert, das der Core
> übrigens selbst lädt, wenn er es benötigt.

Kann es sein, dass Du Dich da auf Perl 5.6 beziehst? Der Satz stammt
nämlich fast wörtlich aus der 5.6-Doku, und in 5.8 hat das utf8-Pragma
eine andere Bedeutung (es sagt aus, dass der Source-Code in UTF-8
geschrieben ist).

> Dein Beispiel gibt übrigens (zumindest bei mir) die Fehler:
>
> Malformed UTF-8 character (unexpected non-continuation byte 0x73,
> immediately af
> ter start byte 0xc4) at z.pl line 6.

Das liegt vermutlich daran, dass Du das File nicht als UTF-8
abgespeichert hast aber das "use utf8" nicht durch ein entsprechendes
"use encoding ..." ersetzt hast.

Es wäre wahrscheinlich sinnvoller gewesen, wenn ich das Ä und das € auch
durch \x-Sequenzen ersetzt hätte, aber ich hielt das "use utf8" für
Dokumentation genug.


> Ist das bei dir auch so?

Nein, ich pflege keine Beispielprogramme zu posten, die Fehler ausgeben,
es sei denn, es kommt mir darauf an, den Fehler zu demonstrieren.

hp

--
_ | Peter J. Holzer | Man könnte sich [die Diskussion] auch
|_|_) | Sysadmin WSR/LUGA | sparen, wenn man sie sich einfach sparen
| | | hjp@hjp.at | würde.
__/ | http://www.hjp.at/ | -- Ralph Angenendt in dang 2006-04-15

Re: [Regex] Suchen nach Hex-Zeichen

am 20.06.2006 00:37:14 von hjp-usenet2

Frank Seitz wrote:
> Slaven Rezic wrote:
>> "Ferry Bolhar" writes:
>>>Peter J. Holzer:
>>>>>Ein String ist in Perl (seit Version 5.6) keine Folge von
>>>>>Bytes, sondern eine Folge von 32-Bit-Werten
>>>
>> "32-Bit-Werte" finde ich auch nicht so glücklich gewählt --- ich würde
>> lieber einfach nur "Integer" oder "Zahl" sagen.

Ok, davon lasse ich mich überzeugen. Ich würde allerdings aus der
Perl-Doku herauslesen, dass es mindestens 32 Bit-Zahlen sind.

>> In den Perl-Interna ist schon alles dafür vorbereitet auch mit größen
>> Zahlen als 32-Bit-Werten für die Unicode-Repräsentation arbeiten zu
>> können.

Mit UTF-8 stößt man da aber bald an die Grenze. Und da 36-Bit-Rechner so
gut wie ausgestorben sind ... (Ha, wir hätten unsere Unisys doch nicht
verschrotten sollen! :-))


> Hm, für mich ist ein String *logisch* immer noch eine Folge von Zeichen,
> nicht von Zahlen oder gar 32-Bit-Werten.

Im Allgemeinen würde ich Dir da zustimmen, in Perl aber nicht. Da kann
ein String alles mögliche sein, nicht nur eine Folge von Zeichen. "Eine
Folge von Zeichen" ist wahrscheinlich die häufigste Anwendung von
Perl-Strings, aber "eine Folge von Bytes" ist vermutlich nicht sehr viel
seltener.

Im wesentlichen liegt am Programmierer zu entscheiden, was ein Scalar
jetzt *logisch* ist. (Hmm, soll ich die Hungarian-Notation-Keule
auspacken? Nein, das lasse ich jetzt lieber)

hp

--
_ | Peter J. Holzer | Man könnte sich [die Diskussion] auch
|_|_) | Sysadmin WSR/LUGA | sparen, wenn man sie sich einfach sparen
| | | hjp@hjp.at | würde.
__/ | http://www.hjp.at/ | -- Ralph Angenendt in dang 2006-04-15

Re: [Regex] Suchen nach Hex-Zeichen

am 20.06.2006 11:20:59 von Frank Seitz

Peter J. Holzer wrote:
> Frank Seitz wrote:
>>
>>Hm, für mich ist ein String *logisch* immer noch eine Folge von Zeichen,
>>nicht von Zahlen oder gar 32-Bit-Werten.
>
> Im Allgemeinen würde ich Dir da zustimmen, in Perl aber nicht. Da kann
> ein String alles mögliche sein, nicht nur eine Folge von Zeichen. "Eine
> Folge von Zeichen" ist wahrscheinlich die häufigste Anwendung von
> Perl-Strings, aber "eine Folge von Bytes" ist vermutlich nicht sehr viel
> seltener.

Echte Binärdaten kommen, so weit ich das sehe, nur selten vor.
Wenn das moderne Perl einen String als eine "Folge von Bytes" ansieht,
also "Byte Semantics" gelten, heißt das nicht, dass diese Daten
nicht aus Zeichen aufgebaut wären. Tatsächlich ist das
fast immer der Fall und so gehen die Programme
mit den Daten auch um.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: [Regex] Suchen nach Hex-Zeichen

am 20.06.2006 11:48:11 von Mirco Wahab

Thus spoke Frank Seitz (on 2006-06-20 11:20):

> Echte Binärdaten kommen, so weit ich das sehe, nur selten vor.
> Wenn das moderne Perl einen String als eine "Folge von Bytes" ansieht,
> also "Byte Semantics" gelten, heißt das nicht, dass diese Daten
> nicht aus Zeichen aufgebaut wären. Tatsächlich ist das
> fast immer der Fall und so gehen die Programme
> mit den Daten auch um.

Das Argument verstehe ich nicht. Eigentlich
ist es doch so, dass sich perl überhaupt nicht
darum kümmert, wie ein Skalar 'datenmässig'
hinter seinem PV* aussieht.

Eben _nur_ dann, wenn dieser in einem Kontext
vorgeholt wird, in dem das Konzept "Folge aus
Zeichen" ansteht, könnte der nächsthöhere
Layer (z.B. eine Funktion) die Daten hinter
diesem PV* so _interpretieren_. Aber in den Daten
selbst würde gar nichts dazu drinstehn, oder doch?


Viele Grüße

Mirco

Re: [Regex] Suchen nach Hex-Zeichen

am 20.06.2006 12:16:21 von Frank Seitz

Mirco Wahab wrote:
> Thus spoke Frank Seitz (on 2006-06-20 11:20):
>>
>>Echte Binärdaten kommen, so weit ich das sehe, nur selten vor.
>>Wenn das moderne Perl einen String als eine "Folge von Bytes" ansieht,
>>also "Byte Semantics" gelten, heißt das nicht, dass diese Daten
>>nicht aus Zeichen aufgebaut wären. Tatsächlich ist das
>>fast immer der Fall und so gehen die Programme
>>mit den Daten auch um.
>
> Das Argument verstehe ich nicht. Eigentlich
> ist es doch so, dass sich perl überhaupt nicht
> darum kümmert, wie ein Skalar 'datenmässig'
> hinter seinem PV* aussieht.

Das moderne Perl unterscheidet, ob
es sich um einen UTF-8 String oder um einen
klassischen String (Bytes) handelt.

> Eben _nur_ dann, wenn dieser in einem Kontext
> vorgeholt wird, in dem das Konzept "Folge aus
> Zeichen" ansteht, könnte der nächsthöhere
> Layer (z.B. eine Funktion) die Daten hinter
> diesem PV* so _interpretieren_. Aber in den Daten
> selbst würde gar nichts dazu drinstehn, oder doch?

Der String wird entsprechend gekennzeichnet,
damit Perl die Daten richtig interpretieren kann.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: [Regex] Suchen nach Hex-Zeichen

am 20.06.2006 13:27:01 von Ferry Bolhar

Peter J Holzer:

>> Was ist an einem String seit 5.6 anders?
>
> Anders ist, dass Du seit 5.6 (theoretisch) bzw. 5.8 (praktisch) eben
> sowas wie
>
> $x = chr(1234) . chr(5678);
>
> schreiben kannst und dann tatsächlich einen String der Länge zwei hast,
> wobei ord(substr($x, 0)) == 1234 und ord(substr($x, 1)) == 5678 ist.

Das sind aber beides keine 32-Bit-Werte. Außerdem bin ich mir nicht
sicher, ob hier tatsächlich eine 32-Bit-Einschränkung besteht; Werte
größer als 2^32-1 werden nicht als IV, sondern als NV abgespeichert,
aber das ist ja wiederum nur eine Frage der Implementierung. Es gibt
ja auch Architekturen, wo ein IV von vorneherein ein 64-Bit-Wert
ist (zB. auf unseren Alphas mit Digital UNIX ist das so).

Ich würde sagen, seit Perl 5.6 werden die Zeichen eines Strings nicht
mehr (umbedingt) als reine Bytewerte abgebildet. Das trifft wohl
am ehersten das, was du gemeint hast?

> Wenn sie - wie Slaven schreibt - den Wertebereich von 32 auf 64 Bit
> erweitern wollen, werden sie müssen. UTF-8 kann nur 36 Bit abdecken.

Ah so? Das ist mir neu. Also meines Wissens sind die Längen wie
folgt festgelegt (Wertbereich des ersten Bytes/Anzahl an Folgebytes
/Gesamtbits):

C0...DF/1/16
E0...EF/2/24
F0...F7/3/32
F8...FB/4/40
FC...FD/5/48
FE/6/56

Wenngleich die Bereiche ab F8 AFAIK dzt.nicht genutzt werden, so sieht
das Codierungsschema doch auch Werte mit bis zu 7 Bytes (56 Bit) vor.

>> denn das würde bedeuten, dass mit 5.8 weggeschriebener Unicode mit
>> künftigen Versionen nicht mehr (oder nur mit Zubauten) lesbar wäre.
>
> Nein, überhaupt nicht. Die interne Repräsentation ist für Perl-Programme
> völlig egal.

Wenn ich Daten nach UTF-8 umwandle und dann wegschreibe,
werde ich beim Einlesen Probleme haben, wenn ich sie als etwas
anderes als UTF-8 interpretiere. Wenn also Perl 5.8 Unicode
Daten im UTF-8-Format abspeichert und auch so wegschreibt,
muss eine spätere Version, die mit diesen Daten wieder arbeiten
möchte, diese auch als UTF-8 interpretieren und entsprechend
zurückwandeln.

Wenn du ASCII-Daten vor dem Wegschreiben in EBCDIC
konvertierst, wird du sie beim Einlesen auch wieder in ASCII
zurückkonvertieren müssen, bevor du sie verwenden kannst.
Unabhängig davon, mit welcher Sprache/Version/usw. du
die Daten weggeschrieben hast. Und wenn die Sprache das
dann in der aktuellen Version nicht (mehr) kann, kannst du
die Daten nicht (mehr) verarbeiten.

Deine Aussage, dass die interne Repräsentation vollkommen
egal sei, kann ich somit nicht nachvollziehen.

>>> Der ganze Rest vom SV. Das sind alles Meta-Informationen, die von
>>> Length nicht berücksichtigt werden. Nein, mit UTF-8 haben sie nichts zu
>>> tun, aber das war ja auch nicht gefragt.

OK, jetzt verstehe ich, was du meinst. Ja, der adminstrative
Overhead beim Abspeichern des Strings 'x' (mindestens 26
Bytes) oder der Zahl 1 (28 Bytes) ist beträchtlich. Aber das
ist eben in der Architektur des SV-Konzeptes begründet.

Mein Statement bezog sich aber auf das Posting von Til:

> len(x)=1, ord(x)=9775
>
> Wie kommt man denn mit einem einzigen Byte aus? Existieren noch
> irgendwo anders (Meta)-Informationen zu diesem String, die von length
> nicht berücksichtigt werden?

aus dem klar hervorgeht, dass damit die Unicode bzw. UTF-8
Verarbeitung gemeint war. Und hier gibt es, wie ich gemeint und
gezeigt habe, nicht mehr "Meta-Informationen" als bei jedem
anderen String.

>> OK, jetzt hast mich erwischt ;-) Ich hätte sagen sollen, "der Perl
>> Core weiß nichts darüber". Die Unicode-Properties sind durch das
>> "utf8" Pragma und seine Subdateien implementiert, das der Core
>> übrigens selbst lädt, wenn er es benötigt.
>
> Kann es sein, dass Du Dich da auf Perl 5.6 beziehst? Der Satz stammt
> nämlich fast wörtlich aus der 5.6-Doku, und in 5.8 hat das utf8-Pragma
> eine andere Bedeutung (es sagt aus, dass der Source-Code in UTF-8
> geschrieben ist).

Das "utf8" Pragma hat im Ladecode eine AUTLOAD-Routine, die
ein 'require "utf8_heavy.pl" ausführt. In dieser Datei und in den von
ihr eingebundenen Dateien findet sich der Unicode-Support.

Der Core lädt utf8.pm, sobald er zB. in einer Regex-Direktive
eine nicht bekannte POSIX-Zeichenklasse, wie zB. eben dein
"\p{Lu}" findet (zumindest tut er das noch in 5.8.7).

Du kannst das leicht selber ausprobieren - benenne die Datei
"utf8.pm" um und du bekommst bei der Ausführung deines Codes
sofort die "Can't locate utf8.pm' Fehlermeldung.

>> Dein Beispiel gibt übrigens (zumindest bei mir) die Fehler:
>>
>> Malformed UTF-8 character (unexpected non-continuation byte 0x73,
>> immediately after start byte 0xc4) at z.pl line 6.
>
> Das liegt vermutlich daran, dass Du das File nicht als UTF-8
> abgespeichert hast aber das "use utf8" nicht durch ein entsprechendes
> "use encoding ..." ersetzt hast.

Ja. Ich wusste auch nicht, dass man das File als UTF-8 abspeichern
muss, damit der Code läuft, denn das hast du nicht dazugesagt.
Außerdem kenne ich (noch) keine Editoren, die Datein in UTF-8
abspeichern können bzw. ergab sich für mich bisher noch nicht
die Notwendigkeit, Programmdateien so abzuspeichern.

LG, Ferry

--
Ing. Ferry Bolhar
Municipality of Vienna, Department 14
A-1010 Vienna / AUSTRIA
E-mail: bol@adv.magwien.gv.at

Re: [Regex] Suchen nach Hex-Zeichen

am 20.06.2006 18:08:23 von hjp-usenet2

Ferry Bolhar wrote:
> Peter J Holzer:
>>> Was ist an einem String seit 5.6 anders?
>>
>> Anders ist, dass Du seit 5.6 (theoretisch) bzw. 5.8 (praktisch) eben
>> sowas wie
>>
>> $x = chr(1234) . chr(5678);
>>
>> schreiben kannst und dann tatsächlich einen String der Länge zwei hast,
>> wobei ord(substr($x, 0)) == 1234 und ord(substr($x, 1)) == 5678 ist.
>
> Das sind aber beides keine 32-Bit-Werte.

Doch. Zugegeben, man kann 1234 auch in 11 Bit und 5678 auch in 13 Bit
ausdrücken, aber auch in 32 Bit.

Der größte Wert, für den das funktioniert, ist aber (zumindest in perl
5.8.x für Intel-Linux) 2**32-1. Wenn ich einen größeren Wert einsetze,
bekomme ich immer "\x{FFFFFFFF}" als Ergebnis (tatsächlich bekomme ich
bei 2*32-2 und 2**32-1 schon Warnings, aber das ist ein anderes
Problem).

> Außerdem bin ich mir nicht sicher, ob hier tatsächlich eine
> 32-Bit-Einschränkung besteht; Werte größer als 2^32-1 werden nicht als
> IV, sondern als NV abgespeichert,

Aber die einzelnen Zeichen eines Strings sind doch keine IVs oder NVs!

In der Perl 5.6-Doku war explizit von 32 Bit die Rede. In der Perl
5.8-Doku finde ich das nicht mehr, nur mehr "larger than 255". Ich gehe
aber davon aus, dass es in jeder Perl-Implementation mindestens 32 Bit
sind und bei der aktuellen Implementation (mittels UTF-8-Kodierung)
können es nicht mehr als 36 Bit sein, aber da diese Implementation IMHO
keineswegs in Stein gemeißelt ist, wäre ich nicht überrascht, wenn es in
perl 5.10 auf 64-Bit-Architekturen 64 Bit wären. Mehr können es werden,
ohne bestehende Programme zu beeinträchtigen, nur weniger nicht.

> Ich würde sagen, seit Perl 5.6 werden die Zeichen eines Strings nicht
> mehr (umbedingt) als reine Bytewerte abgebildet. Das trifft wohl
> am ehersten das, was du gemeint hast?

"nicht reine Byte-Werte" ist sehr schwammig. Was ist ein unreiner
Byte-Wert. Ich gehe davon aus, dass die Zeichen eines Strings
nicht-negative ganze Zahlen aus einem Bereich [0 .. N] sind (bzw.
eineindeutig darauf abgebildet werden können, wenn man wie Frank Zeichen
nicht als Zahlen sehen will), wobei N mindestens 2**32-1 ist. Letzteres
steht zwar nicht mehr direkt in der Doku, aber ein Wertebereich bis
mindestens 2**21-1 ergibt sich allein daraus, dass man alle
Unicode-Zeichen abdecken können möchte (und das steht explizit in der
Doku).


>> Wenn sie - wie Slaven schreibt - den Wertebereich von 32 auf 64 Bit
>> erweitern wollen, werden sie müssen. UTF-8 kann nur 36 Bit abdecken.
>
> Ah so? Das ist mir neu. Also meines Wissens sind die Längen wie
> folgt festgelegt (Wertbereich des ersten Bytes/Anzahl an Folgebytes
> /Gesamtbits):
>
> C0...DF/1/16
> E0...EF/2/24
> F0...F7/3/32
> F8...FB/4/40
> FC...FD/5/48
> FE/6/56

Du rechnest da den Overhead von UTF-8 mit. In einer 7-Byte UTF-8-Folge
hast Du nur 36-Datenbits: Das erste Byte dient vollständig dazu, den
Anfang einer 7-Byte langen UTF-8-Folge anzukündigen, und die folgenden 6
Bytes enthalten je 6 Daten-Bits (die oberen 2 Bits sind immer "10").

Die Anzahl der Datenbits in UTF-8-Kodierungen ist wie folgt:

7 = 7
5+6 = 11
4+6+6 = 16
3+6+6+6 = 21
2+6+6+6+6 = 26
1+6+6+6+6+6 = 31
0+6+6+6+6+6+6 = 36

Danach müsste das erste Byte weniger als 0 Datenbits enthalten und das
geht halt nicht. (Der findige Leser wird bemerken, dass der Code 0xFF
noch unbenutzt ist: Richtig, der könnte zur Erweiterung benutzt werden,
aber das ist dann nicht mehr UTF-8, sondern eine Erweiterung von UTF-8)

>>> denn das würde bedeuten, dass mit 5.8 weggeschriebener Unicode mit
>>> künftigen Versionen nicht mehr (oder nur mit Zubauten) lesbar wäre.
>>
>> Nein, überhaupt nicht. Die interne Repräsentation ist für Perl-Programme
>> völlig egal.
>
> Wenn ich Daten nach UTF-8 umwandle und dann wegschreibe,
> werde ich beim Einlesen Probleme haben, wenn ich sie als etwas
> anderes als UTF-8 interpretiere.

Da, aber das hat nichts mit der *internen* Repräsentation zu tun.

> Wenn also Perl 5.8 Unicode Daten im UTF-8-Format abspeichert und auch
> so wegschreibt,

Das ist schon falsch. Wie Perl Daten wegschreibt, hat *nichts* damit zu
tun, wie es diese Daten speichert. Das hängt aussschließlich von
den I/O-Layern ab.

> muss eine spätere Version, die mit diesen Daten wieder arbeiten
> möchte, diese auch als UTF-8 interpretieren und entsprechend
> zurückwandeln.

Ja, und das macht man indem man einen passenden I/O-Layer angibt. Wenn
Du ein File mit open($fh, "<:utf8", $filename) öffnest, wird von UTF-8
in die interne Repräsentation umgewandelt. Ob diese interne
Repräsentation jetzt UTF-8 oder Morse-Alphabet ist, ist egal.


> Wenn du ASCII-Daten vor dem Wegschreiben in EBCDIC
> konvertierst, wird du sie beim Einlesen auch wieder in ASCII
> zurückkonvertieren müssen, bevor du sie verwenden kannst.
> Unabhängig davon, mit welcher Sprache/Version/usw. du
> die Daten weggeschrieben hast. Und wenn die Sprache das
> dann in der aktuellen Version nicht (mehr) kann, kannst du
> die Daten nicht (mehr) verarbeiten.

Wer redet davon, dass Perl kein UTF-8 mehr können soll? Es ist nur davon
die Rede, dass die interne Repräsentation anders sein könnte.

> Deine Aussage, dass die interne Repräsentation vollkommen
> egal sei, kann ich somit nicht nachvollziehen.

Dir ist also bisher sowohl die Existenz von I/O-Layern als auch von
encode/decode verborgen geblieben? Wenn man die richtig anwendet, ist
die interne Repräsentation tatsächlich vollkommen egal. Tatsächlich hat
man als Perl-Programmierer wenig Kontrolle darüber, ob man mit UTF-8-
oder Byte-Strings arbeitet und meistens ist es auch vollkommen egal.


>>> Dein Beispiel gibt übrigens (zumindest bei mir) die Fehler:
>>>
>>> Malformed UTF-8 character (unexpected non-continuation byte 0x73,
>>> immediately after start byte 0xc4) at z.pl line 6.
>>
>> Das liegt vermutlich daran, dass Du das File nicht als UTF-8
>> abgespeichert hast aber das "use utf8" nicht durch ein entsprechendes
>> "use encoding ..." ersetzt hast.
>
> Ja. Ich wusste auch nicht, dass man das File als UTF-8 abspeichern
> muss, damit der Code läuft, denn das hast du nicht dazugesagt.

Ich habe "use utf8;" geschrieben und das bedeutet, dass der Source-Code
utf8 ist. Ich gebe zu, dass das leicht zu übersehen war.

> Außerdem kenne ich (noch) keine Editoren, die Datein in UTF-8
> abspeichern können

vim, emacs, ...

Gibt es unter Linux irgendeinen ernstzunehmenden Editor, der nicht
UTF-8-tauglich ist?

> die Notwendigkeit, Programmdateien so abzuspeichern.

Die Notwendigkeit vielleicht nicht unbedingt, aber es ist halt
praktischer, "Ä" zu schreiben als "\x{C4}" oder gar
"\N{LATIN CAPITAL LETTER A WITH DIAERESIS}". Und da meine Systeme (die
neueren zumindest) UTF-8 als System-Charset haben, wäre die Verwendung
eines anderen Encodings unsinnig.

hp

--
_ | Peter J. Holzer | Man könnte sich [die Diskussion] auch
|_|_) | Sysadmin WSR/LUGA | sparen, wenn man sie sich einfach sparen
| | | hjp@hjp.at | würde.
__/ | http://www.hjp.at/ | -- Ralph Angenendt in dang 2006-04-15

Re: [Regex] Suchen nach Hex-Zeichen

am 20.06.2006 18:25:03 von hjp-usenet2

Frank Seitz wrote:
> Peter J. Holzer wrote:
>> Frank Seitz wrote:
>>>Hm, für mich ist ein String *logisch* immer noch eine Folge von Zeichen,
>>>nicht von Zahlen oder gar 32-Bit-Werten.
>>
>> Im Allgemeinen würde ich Dir da zustimmen, in Perl aber nicht. Da kann
>> ein String alles mögliche sein, nicht nur eine Folge von Zeichen. "Eine
>> Folge von Zeichen" ist wahrscheinlich die häufigste Anwendung von
>> Perl-Strings, aber "eine Folge von Bytes" ist vermutlich nicht sehr viel
>> seltener.
>
> Echte Binärdaten kommen, so weit ich das sehe, nur selten vor.
> Wenn das moderne Perl einen String als eine "Folge von Bytes" ansieht,
> also "Byte Semantics" gelten, heißt das nicht, dass diese Daten
> nicht aus Zeichen aufgebaut wären.

Richtig. Das hat damit nichts zu tun. Die Unterscheidung von Bytes und
Zeichen ist eine semantische, die auf der Applikationsebene getroffen
werden muss.

> Tatsächlich ist das fast immer der Fall und so gehen die Programme mit
> den Daten auch um.

Drei Gegenbeispiele:

* Ich habe eine Backup-Software in Perl geschrieben. Der ist der Inhalt
der Files völlig egal - ein File ist einfach nur eine Folge von Bytes,
ob darin nun Text oder ein Video steht.

* Ich verwende qpsmtpd als SMTP-Server. Der ist in Perl geschrieben.
Teilweise interpretiert er die Daten, die durchschleust werden, als
Zeichen, vor allem bei SMTP-Kommandos, aber auch z.B. bei der Analyse
von Headern. Mengenmäßig besteht aber wahrscheinlich der größte Teil von
Daten, die er durschleust, aus Base-64-kodierten Word-Dokumenten. Und
die kann ich beim besten Willen nur als binär ansehen, auch wenn die
Bytes den gleichen Wertebereich haben wie druckbare ASCII-Zeichen. Das
Byte 0x65 ist da eben kein "A", auch wenn es natürlich so ausschaut,
wenn ich es im Editor betrachte, sondern nur die Kodierung der Bitfolge
000000.

* use GD;
$im = new GD::Image(100,100);
$x = $im->png;
In $x steht nun ein String. Aber dieser besteht nicht aus Zeichen,
sondern aus Bytes, deren Bedeutung im RFC 2083 nachzulesen ist.


Dass es Programmierern oft schwerfällt, zwischen Bytes und Zeichen zu
unterscheiden (und ihnen das von Programmiersprachen wie C oder Perl
nicht leichtgemacht wird) ist IMHO eine häufige Ursache von Bugs auf dem
Gebiet.

hp

--
_ | Peter J. Holzer | Man könnte sich [die Diskussion] auch
|_|_) | Sysadmin WSR/LUGA | sparen, wenn man sie sich einfach sparen
| | | hjp@hjp.at | würde.
__/ | http://www.hjp.at/ | -- Ralph Angenendt in dang 2006-04-15

Re: [Regex] Suchen nach Hex-Zeichen

am 20.06.2006 19:03:30 von KWittrock

Hallo Peter,

"Peter J. Holzer" schrieb im Newsbeitrag
news:u6877e.i2p.ln@teal.hjp.at...
> ........
>> Dein Beispiel gibt übrigens (zumindest bei mir) die Fehler:
>>
>> Malformed UTF-8 character (unexpected non-continuation byte 0x73,
>> immediately af
>> ter start byte 0xc4) at z.pl line 6.
>
> Das liegt vermutlich daran, dass Du das File nicht als UTF-8
> abgespeichert hast aber das "use utf8" nicht durch ein entsprechendes
> "use encoding ..." ersetzt hast.
>
> Es wäre wahrscheinlich sinnvoller gewesen, wenn ich das Ä und das € auch
> durch \x-Sequenzen ersetzt hätte, aber ich hielt das "use utf8" für
> Dokumentation genug.
> ........

Ich habe jetzt dein Beispiel per Drag & Drop nach Word übernommen und dort
als Utf8-kodierte Textdatei gespeichert. Ok, die "Malformed UTF-8"-Meldungen
sind jetzt weg. Als Ausgabe erhalte ich

A
─
Wide character in print at E:\Klaus\Perl\Test\unic_mit_utf8.pl line 11.
Α
no match

und nach Entfernen von use utf8;

A
├
Wide character in print at E:\Klaus\Perl\Test\unic_ohne_utf8.pl line 11.
Α
no match

Die erstgenannte Ausgabe erhalte ich übrigens auch, wenn ich das Skript
"ganz normal" im Editor abspeichere, nachdem ich
use utf8; entfernt habe. Die Ausgaben weichen von deinen deutlich ab. Kann
das daran liegen, dass bei meinem Perl die
Unicode-Unterstützung noch zu instabil ist? Ich benutze z. Zt. noch Perl
v5.8.4 build 810 von ActiveState.

Zusatzfrage: Warum muss ich ein Skript, welches nur ANSI-Zeichen enthält,
als Utf8 abspeichern, damit es richtig interpretiert wird? An Ä und € kann's
ja wohl nicht liegen (ord('Ä') = 0xc4, ord('€') = 0x80).

Gruß

Klaus

Re: [Regex] Suchen nach Hex-Zeichen

am 20.06.2006 23:02:48 von hjp-usenet2

K. Wittrock wrote:
> Ich habe jetzt dein Beispiel per Drag & Drop nach Word übernommen und dort
> als Utf8-kodierte Textdatei gespeichert. Ok, die "Malformed UTF-8"-Meldungen
> sind jetzt weg. Als Ausgabe erhalte ich
>
> A
> ─
> Wide character in print at E:\Klaus\Perl\Test\unic_mit_utf8.pl line 11.
> Α
> no match

Aus "Word" und "Activestate" schließe ich mal "Windows".
Hmm, mit Windows kenne ich mich nicht aus. Die Zeichen schauen nach
"Drawing Characters" aus: Eine horizontale Linie und ein halber Block
oben? Verwendet Windows in der Konsole noch die MS-DOS-Codepages? Dann
müsste das wohl CP-850 sein, und man müsste zur korrekten Ausgabe ein

binmode STDOUT, ":encoding(cp-850)";

vor die erste Ausgabe schreiben, um von Perl-interner Repräsentation
nach CP850 umzuwandeln. (Es sollte ein Flag oder eine
Environment-Variable geben, die das automatisch macht - irgendwie zeigt
sich da ein gewisser iso-8859-1-Zentrismus der Perl-Entwickler).

In diesem speziellen Fall hilft das aber wenig, da das Programm ein
großes Alpha ausgeben möchte und ein solches ist in CP-850 einfach nicht
vorhanden.

Unter Linux funktioniert das übrigens natürlich auch nur, wenn man ein
UTF-8-Terminal verwendet und die entsprechenden Environment-Variablen
richtig gesetzt hat:

LANG=en_US.UTF-8 (oder sonst was mit UTF-8)
PERL_UNICODE=SDAL ("SDA" heißt "Standard-Streams, neue Streams und ARGV
sind UTF-8, "L" heißt "aber nur in einer UTF-8
Locale")

Kann sein, dass man unter Windows auch irgendwas spezielles machen muss,
damit UTF-8 I/O "von selbst" funktioniert.


> Die erstgenannte Ausgabe erhalte ich übrigens auch, wenn ich das Skript
> "ganz normal" im Editor abspeichere, nachdem ich
> use utf8; entfernt habe.

Was auch immer "ganz normal" bei dem von Dir verwendeten Editor bedeuten
mag ;-). Wenn es Windows-1252 ist, überrascht mich das nicht, denn der
einzige Unterschied wäre dann das Euro-Zeichen und das wird nicht
ausgegeben.

> Zusatzfrage: Warum muss ich ein Skript, welches nur ANSI-Zeichen enthält,
> als Utf8 abspeichern, damit es richtig interpretiert wird?

Weil im Script selbst steht, dass es in UTF-8 abgespeichert ist (das ist
die Bedeutung von "use utf8;").

> An Ä und € kann's
> ja wohl nicht liegen (ord('Ä') = 0xc4, ord('€') = 0x80).

Doch, an genau diesen liegt's. Die sind nämlich nicht US-ASCII, und
daher muss Perl wissen, in welchem Zeichensatz das Script abgespeichert
wurde, um sie richtig interpretieren zu können.

Ich bezweifle übrigens stark, dass es irgendeinen ANSI-Standard gibt, in
dem ord('€') = 0x80 festgelegt ist. Das ist meines Wissens Windows-1252,
nix ANSI. Für Perl gilt übrigens: ord('€') = 0x20AC, wenn man von
Strings mit Character-Semantik spricht und nicht von einem bestimmten
Encoding.

hp

--
_ | Peter J. Holzer | Man könnte sich [die Diskussion] auch
|_|_) | Sysadmin WSR/LUGA | sparen, wenn man sie sich einfach sparen
| | | hjp@hjp.at | würde.
__/ | http://www.hjp.at/ | -- Ralph Angenendt in dang 2006-04-15

Re: [Regex] Suchen nach Hex-Zeichen

am 21.06.2006 00:08:20 von Slaven Rezic

"Peter J. Holzer" writes:

> (Es sollte ein Flag oder eine
> Environment-Variable geben, die das automatisch macht - irgendwie zeigt
> sich da ein gewisser iso-8859-1-Zentrismus der Perl-Entwickler).

iso-8859-1- *und* UTF-8-Zentrismus --- immerhin gibt es
Environment-Variablen, die beim Letzteren helfen, wie du später auch
selbst schreibst:

> und die entsprechenden Environment-Variablen
> richtig gesetzt hat:
>
> LANG=en_US.UTF-8 (oder sonst was mit UTF-8)
> PERL_UNICODE=SDAL ("SDA" heißt "Standard-Streams, neue Streams und ARGV
> sind UTF-8, "L" heißt "aber nur in einer UTF-8
> Locale")

Gruß,
Slaven

--
Slaven Rezic - slaven rezic de

tkruler - Perl/Tk program for measuring screen distances
http://ptktools.sourceforge.net/#tkruler

Re: [Regex] Suchen nach Hex-Zeichen

am 21.06.2006 10:22:50 von KWittrock

Hallo Til,

"Til Schubbe" schrieb im Newsbeitrag
news:slrne9ab0u.run.usenet@news001.schubbi-news.com...
> ......
> Eigentlich war's eine allgemeine Frage, wie man beliebig
> lange Hex-Strings als Muster angeben kann.
>
> Konkret möchte ich in einem String jedes Vorkommen von \x00\x00\x0a
> löschen. Und da wäre \x{00000a} halt kürzer gewesen.

Wenn's dir darum geht, Tipparbeit zu sparen, versuch doch mal \0\0\n .

Gruß

Klaus

Re: [Regex] Suchen nach Hex-Zeichen

am 23.06.2006 12:55:57 von Ferry Bolhar

Peter J. Holzer:

>> Das sind aber beides keine 32-Bit-Werte.
>
> Doch. Zugegeben, man kann 1234 auch in 11 Bit und 5678 auch in 13 Bit
> ausdrücken, aber auch in 32 Bit.

Man kann sie auch in 64, 128 oder 256 Bit oder noch mehr "ausdrücken",
das macht sie aber noch nicht zu solchen Werten.

>>> Wenn sie - wie Slaven schreibt - den Wertebereich von 32 auf 64 Bit
>>> erweitern wollen, werden sie müssen. UTF-8 kann nur 36 Bit abdecken.
> >
>> Ah so? Das ist mir neu.

[..]

> Du rechnest da den Overhead von UTF-8 mit. In einer 7-Byte UTF-8-Folge
> hast Du nur 36-Datenbits:

OK, danke für die Klarstellung.

> Wer redet davon, dass Perl kein UTF-8 mehr können soll? Es ist nur davon
> die Rede, dass die interne Repräsentation anders sein könnte.

[...]

> Dir ist also bisher sowohl die Existenz von I/O-Layern als auch von
> encode/decode verborgen geblieben? Wenn man die richtig anwendet, ist
> die interne Repräsentation tatsächlich vollkommen egal. Tatsächlich hat
> man als Perl-Programmierer wenig Kontrolle darüber, ob man mit UTF-8-
> oder Byte-Strings arbeitet und meistens ist es auch vollkommen egal.

Wenn ich mir das so durchlese, glaube ich, dass wir aneinander vorbei-
reden, weil du (zu) theoretisch und ich (zu) praktisch denke. Es ist schon
klar, dass man mit Hilfe von I/O Layern Daten wahrscheinlich auch so
abspeichern kann, dass sie zusammengesetzt ein Kreuzworträtsel ergeben.
Die Frage ist nur, wie sinnvoll das ist und welchen Aufwand man dafür
betreiben muss. Und was jetzt mit dieser Erkenntnis bewiesen werden soll.

Ich denke geradlinig: wenn ich mit Perl Version X Daten UTF-8 kodiert
wegschreiben kann, dann möchte ich sie mit Version X+1 genauso wieder
einlesen können, ohne I/O Layer oder zusätzliche Module; sprich, ich möchte
sie mitdenselben Mitteln einlesen können, mit denen ich sie weggeschrieben
habe. Und das bedeutet, dass die Version X+1 dasselbe Codierungsschema
zum Einlesen verwenden muss, das die Version X zum Wegschreiben ver-
wendet hat. Bei Perl hat man sich hier auf UTF-8 festlegt (dh., man hat,
unge-
achtet aller sonstigen I/O Layer und Encoding/Decoding-Module, Routinen
zum Konvertieren von/nach UTF-8 in den Core eingebaut). Das habe ich
gemeint, als ich schrieb, dass Perl kein Unicode kann, sondern nur UTF-8 -
die einzige Möglichkeit, die der Core zum Speichern von Zeichenwerten > 255
vorsieht, ist UTF-8. Und das muss daher auch in künftigen Versionen so
bleiben.

Was dann ein Programm daraus macht und welche Module/Layer/usw. für
sonstige Kodierungen zur Verfügung stehen, steht auf einem ganz anderen
Blatt.

>> Wenn also Perl 5.8 Unicode Daten im UTF-8-Format abspeichert
>> und auch so wegschreibt,

> Das ist schon falsch. Wie Perl Daten wegschreibt, hat *nichts* damit zu
> tun, wie es diese Daten speichert. Das hängt aussschließlich von
> den I/O-Layern ab.

Nein, nicht umbedingt. Ich muss ja keine I/O Layer verwenden. Von was
hängt es dann ab?

>> muss eine spätere Version, die mit diesen Daten wieder arbeiten
>> möchte, diese auch als UTF-8 interpretieren und entsprechend
>> zurückwandeln.

> Ja, und das macht man indem man einen passenden I/O-Layer angibt

Das ist - theoretisch gedacht - vielleicht eine Variante, praktisch aber
sicher ein Nachteil. Wenn ich mit einem Werkzeug in einer bestimmten
Art und Weise Daten wegschreibe, dann möchte ich sie mit demselben
Werkzeug auf dieselbe Weise (dh., ohne irgendwelche Zubauten)
wieder einlesen können. Ich würde es strikt ablehnen, ein Werkzeug
zu benutzen, bei dem in einer höheren (anderen) Version eine vorherige
Basisfunktionalität nur mehr mit Zubauten, die ich händisch laden/
aufrufen/angeben/installieren/usw. muss, bereitgestellt wird.

Schöne Grüße aus Wien,

Ferry

--
Ing. Ferry Bolhar
Municipality of Vienna, Department 14
A-1010 Vienna / AUSTRIA
E-mail: bol@adv.magwien.gv.at

Re: [Regex] Suchen nach Hex-Zeichen

am 23.06.2006 14:55:30 von KWittrock

"Peter J. Holzer" schrieb im Newsbeitrag
news:opn97e.t94.ln@teal.hjp.at...
> K. Wittrock wrote:
>> Ich habe jetzt dein Beispiel per Drag & Drop nach Word übernommen und
>> dort
>> als Utf8-kodierte Textdatei gespeichert. Ok, die "Malformed
>> UTF-8"-Meldungen
>> sind jetzt weg. Als Ausgabe erhalte ich
>>
>> A
>> ─
>> Wide character in print at E:\Klaus\Perl\Test\unic_mit_utf8.pl line 11.
>> Α
>> no match
>
> Aus "Word" und "Activestate" schließe ich mal "Windows".

Richtig. Im DOS-Fenster (auf das man bei Perl nur schwer verzichten kann)
werden die Umlaute und noch einiges andere verhunzt. Daran hätte ich denken
müssen.

>> Die erstgenannte Ausgabe erhalte ich übrigens auch, wenn ich das Skript
>> "ganz normal" im Editor abspeichere, nachdem ich
>> use utf8; entfernt habe.
>
> Was auch immer "ganz normal" bei dem von Dir verwendeten Editor bedeuten
> mag ;-).

Ich meinte "speichern als simple Textdatei".

>> Zusatzfrage: Warum muss ich ein Skript, welches nur ANSI-Zeichen enthält,
>> als Utf8 abspeichern, damit es richtig interpretiert wird?
>
> Weil im Script selbst steht, dass es in UTF-8 abgespeichert ist (das ist
> die Bedeutung von "use utf8;").
>
>> An Ä und € kann's
>> ja wohl nicht liegen (ord('Ä') = 0xc4, ord('€') = 0x80).
>
> Doch, an genau diesen liegt's. Die sind nämlich nicht US-ASCII, und
> daher muss Perl wissen, in welchem Zeichensatz das Script abgespeichert
> wurde, um sie richtig interpretieren zu können.

Mit Ä hatte ich noch nie Probleme. Über € kann ich nichts sagen, da ich es
nur selten benutze.Aber ich vermute, dass Perl auch ohne "use utf8;" mit
allen Strings klarkommt, in denen nur Zeichen bis 0xFF vorkommen, solange
man Strings als Zeichenfolgen betrachtet und nicht die Plattform wechselt.

> Ich bezweifle übrigens stark, dass es irgendeinen ANSI-Standard gibt, in
> dem ord('€') = 0x80 festgelegt ist.

Richtig. Das €-Zeichen kam so spät, dass sich niemand mehr die Mühe gemacht
hat, das in ANSI zu normen.

Wir leben bezüglich Unicode in einer Übergangszeit und werden wohl noch eine
Weile mit Unzulänglichkeiten leben müssen. Übrigens ist da Open Office unter
Knoppix besonders nett: Beim Import von MS Word setzt es € richtig nach 0xa4
um, zeigt es aber nicht an (auch kein neu eingegebenes €). Wenn man ein
Textstück in ein neues Dokument oder ein Konsolfenster kopiert, ist das €
plötzlich da. Im Kamel-Buch lautet der letzte Satz im Unicode-Kapitel:
"Unicode macht Spaß - Sie müssen Spaß nur richtig definieren".

Gruß

Klaus

Re: [Regex] Suchen nach Hex-Zeichen

am 23.06.2006 22:14:57 von hjp-usenet2

Ferry Bolhar wrote:

> Peter J. Holzer:
>
>>> Das sind aber beides keine 32-Bit-Werte.
>>
>> Doch. Zugegeben, man kann 1234 auch in 11 Bit und 5678 auch in 13 Bit
>> ausdrücken, aber auch in 32 Bit.
>
> Man kann sie auch in 64, 128 oder 256 Bit oder noch mehr "ausdrücken",
> das macht sie aber noch nicht zu solchen Werten.

Mein lieber Ferry, Du gehst mir gewaltig auf den Zeiger!

Die Werte 1234 und 5678 waren Beispiele. Sie sollten nicht den
Maximalwert darstellen (zwei Maximalwerte wären ja auch nicht sehr
sinnvoll), sondern nur demonstrieren, dass Werte über 255 möglich sind.
Die Verallgemeinerung, dass alle Werte von 0 bis 2**32-1 möglich sind,
wenn ich von 32-Bit-Werten schreibe, und nicht nur die beiden, die ich
als Beispiele angeführt habe, traue ich dem durchschnittlichen Leser
dieser Newsgroup zu.

>> Dir ist also bisher sowohl die Existenz von I/O-Layern als auch von
>> encode/decode verborgen geblieben? Wenn man die richtig anwendet, ist
>> die interne Repräsentation tatsächlich vollkommen egal. Tatsächlich hat
>> man als Perl-Programmierer wenig Kontrolle darüber, ob man mit UTF-8-
>> oder Byte-Strings arbeitet und meistens ist es auch vollkommen egal.
>
> Wenn ich mir das so durchlese, glaube ich, dass wir aneinander vorbei-
> reden, weil du (zu) theoretisch und ich (zu) praktisch denke.

Ich denke da durchaus praktisch. Das Wegabstrahieren von Eigenschaften
einer bestimmten Implementation hilft, korrekte und portable Programme
zu schreiben. Es hilft mir auch, mich auf das Wesentliche zu
konzentrieren. Wenn ich Perl schreibe, ist ein Scalar für mich ein
Scalar, nicht ein struct mit einem Pointer auf ein zweites struct mit
einem Pointer auf einen String. Wollte ich mich um sowas kümmern, würde
ich C programmieren. Theoretisch ist es interessant, was Perl da intern
macht, aber praktisch spielt es keine Rolle.


> Es ist schon klar, dass man mit Hilfe von I/O Layern Daten
> wahrscheinlich auch so abspeichern kann, dass sie zusammengesetzt ein
> Kreuzworträtsel ergeben. Die Frage ist nur, wie sinnvoll das ist und
> welchen Aufwand man dafür betreiben muss. Und was jetzt mit dieser
> Erkenntnis bewiesen werden soll.
>
> Ich denke geradlinig: wenn ich mit Perl Version X Daten UTF-8 kodiert
> wegschreiben kann,

Das kannst Du aber nicht. Probier's aus. Wenn Du Deine Daten als UTF-8
schreiben willst, musst Du Perl explizit sagen, dass Du das tun willst,
entweder über über einen I/O-Layer oder über expliziten Aufruf von
encode.

Kleines Testprogramm:
---8<------8<------8<------8<------8<------8<------8<------8<---
#!/usr/bin/perl
use warnings;
use strict;

my $x = "\x{FC}";
utf8::upgrade($x);

print "is_utf8: ", utf8::is_utf8($x), "\n";
print "$x\n";
---8<------8<------8<------8<------8<------8<------8<------8<---
Der Output ist nicht UTF-8!

> dann möchte ich sie mit Version X+1 genauso wieder einlesen können,
> ohne I/O Layer oder zusätzliche Module; sprich, ich möchte sie
> mitdenselben Mitteln einlesen können, mit denen ich sie weggeschrieben
> habe.

Genau so ist es: Du brauchst den I/O-Layer zum Schreiben und zum Lesen.
Vollkommen konsistent.

> Was dann ein Programm daraus macht und welche Module/Layer/usw. für
> sonstige Kodierungen zur Verfügung stehen, steht auf einem ganz anderen
> Blatt.
>
>>> Wenn also Perl 5.8 Unicode Daten im UTF-8-Format abspeichert
>>> und auch so wegschreibt,
>
>> Das ist schon falsch. Wie Perl Daten wegschreibt, hat *nichts* damit zu
>> tun, wie es diese Daten speichert. Das hängt aussschließlich von
>> den I/O-Layern ab.
>
> Nein, nicht umbedingt. Ich muss ja keine I/O Layer verwenden. Von was
> hängt es dann ab?

Wenn Du keine I/O-Layer verwendest, liest/schreibst Du nicht UTF-8,
sondern raw (d.h., 1 Zeichen <-> 1 Byte), außer denn der String ein
Zeichen > 255 enthält, dann ist es UTF-8 und Du bekommst eine Warnung.
De facto ist das aber nur für Daten mit allen Zeichen <= 255 brauchbar,
weil Du sonst vollkommen inkonsistenten Output bekommst. Wenn Du in
einem Charset (auch UTF-8) schreiben und lesen willst, musst Du
I/O-Layer verwenden.

>>> muss eine spätere Version, die mit diesen Daten wieder arbeiten
>>> möchte, diese auch als UTF-8 interpretieren und entsprechend
>>> zurückwandeln.
>
>> Ja, und das macht man indem man einen passenden I/O-Layer angibt
>
> Das ist - theoretisch gedacht - vielleicht eine Variante, praktisch aber
> sicher ein Nachteil.

Nein, es ist praktisch die einzige Möglichkeit.

hp

--
_ | Peter J. Holzer | Man könnte sich [die Diskussion] auch
|_|_) | Sysadmin WSR/LUGA | sparen, wenn man sie sich einfach sparen
| | | hjp@hjp.at | würde.
__/ | http://www.hjp.at/ | -- Ralph Angenendt in dang 2006-04-15

Re: [Regex] Suchen nach Hex-Zeichen

am 23.06.2006 22:37:30 von hjp-usenet2

K. Wittrock wrote:
> "Peter J. Holzer" schrieb im Newsbeitrag
> news:opn97e.t94.ln@teal.hjp.at...
>> K. Wittrock wrote:
>>
>> Aus "Word" und "Activestate" schließe ich mal "Windows".
>
Irgendwie scheint mir zwischen:

> Im DOS-Fenster (auf das man bei Perl nur schwer verzichten kann)
> werden die Umlaute und noch einiges andere verhunzt. Daran hätte ich
> denken müssen.

und

> Mit Ä hatte ich noch nie Probleme.

ein leichter Widerspruch zu bestehen. Werden Umlaute nun verhunzt oder
hast Du keine Probleme mit ihnen? Oder ist es kein Problem, dass sie
verhunzt werden?


>>> Die erstgenannte Ausgabe erhalte ich übrigens auch, wenn ich das Skript
>>> "ganz normal" im Editor abspeichere, nachdem ich
>>> use utf8; entfernt habe.
>>
>> Was auch immer "ganz normal" bei dem von Dir verwendeten Editor bedeuten
>> mag ;-).
>
> Ich meinte "speichern als simple Textdatei".

"Simple Textdateien" gibt es halt auf einem System wie Windows, auf dem
mindestens 4 verschiedene Charsets üblich sind, nicht :-(.


>>> An Ä und € kann's ja wohl nicht liegen (ord('Ä') = 0xc4, ord('€') =
>>> 0x80).
>>
>> Doch, an genau diesen liegt's. Die sind nämlich nicht US-ASCII, und
>> daher muss Perl wissen, in welchem Zeichensatz das Script abgespeichert
>> wurde, um sie richtig interpretieren zu können.
>
> Mit Ä hatte ich noch nie Probleme. Über € kann ich nichts sagen, da ich es
> nur selten benutze.Aber ich vermute, dass Perl auch ohne "use utf8;" mit
> allen Strings klarkommt, in denen nur Zeichen bis 0xFF vorkommen, solange
> man Strings als Zeichenfolgen betrachtet und nicht die Plattform wechselt.

Das kommt darauf an, was man mit den Strings macht. Bei vielen
Operationen ist es tatsächlich völlig egal, welcher Code welches Zeichen
darstellt. Bei anderen nicht: Wenn Du z.B. Kleinbuchstaben in
Großbuchstaben umwandeln willst, muss perl wissen, welche Codes
Kleinbuchstaben darstellen und welche Codes die entsprechenden
Großbuchstaben haben. Wenn Du z.B. den String "ä" in CP850 hast, dann
besteht der aus einem Zeichen mit dem Code 0x84. Wenn perl nun glaubt,
dass Du Unicode verwendest, dann glaubt es, dass das ein
Control-Character ist, und wird keinen dazu passenden Großbuchstaben
finden. Noch schlimmer ist es bei "õ" (0xE4): Das ist auch in Unicode
ein Kleinbuchstabe, aber ein anderer (nämlich ein "ä"). Also wird Perl
den in diesem Fall durch den Code des "Ä" (0xC4) ersetzen. 0xC4 ist in
CP850 aber ein waagrechter Strich, richtig wäre (0xE5) gewesen.

> Wir leben bezüglich Unicode in einer Übergangszeit und werden wohl noch eine
> Weile mit Unzulänglichkeiten leben müssen. Übrigens ist da Open Office unter
> Knoppix besonders nett: Beim Import von MS Word setzt es € richtig nach 0xa4
> um,

Warum soll das richtig sein? Open Office (zumindest Version 2.0)
verwendet intern Unicode, da hat ein € den Code U+20AC. U+00A4 ist das
Currency Sign (auch als "Dübel" bekannt). Den Code 0xA4 hat das € im
Zeichensatz ISO-8859-15. Aber irgendwie wird das off-topic.

hp

--
_ | Peter J. Holzer | Man könnte sich [die Diskussion] auch
|_|_) | Sysadmin WSR/LUGA | sparen, wenn man sie sich einfach sparen
| | | hjp@hjp.at | würde.
__/ | http://www.hjp.at/ | -- Ralph Angenendt in dang 2006-04-15

Re: [Regex] Suchen nach Hex-Zeichen

am 26.06.2006 12:58:04 von Ferry Bolhar

Peter J. Holzer:

> Mein lieber Ferry, Du gehst mir gewaltig auf den Zeiger!

Das tut mir leid, es war nicht meine Absicht. Ich mag nur keine
Ungenauigkeiten.

> Die Werte 1234 und 5678 waren Beispiele.

Und? Was wolltest du mit diesen Beispielen zeigen oder beweisen?

>> Wenn ich mir das so durchlese, glaube ich, dass wir aneinander vorbei-
>> reden, weil du (zu) theoretisch und ich (zu) praktisch denke.
>
> Ich denke da durchaus praktisch. Das Wegabstrahieren von Eigenschaften
> einer bestimmten Implementation hilft, korrekte und portable Programme
> zu schreiben.

Es ist nur in Diskussionen, wo es eben um diese Eigenschaften geht,
wenig hilfreich. Wenn ich schreibe, dass auch in Perl 5.6 und 5.8
Strings normalerweise (wie mein Beispiel "hello") in Bytes abge-
speichert werden, hilft es nicht sehr, wenn du meinst, dass dies seit
Perl 5.6 String in "logischen 32-Bit-Werten" geschieht.

Was willst du damit aussagen? Wie sieht "hello" als "logischer 32-
Bit-Wert" abgespeichert aus?

Und wie ich auch geschrieben habe, gbit es eben Plattformen, auf
denen ein IV 64 Bit umfasst. Gibt es dort dann "logische 64-Bit-
Werte"?

Aber bevor ich dir noch mehr "auf den Zeiger gehe", höre ich
lieber auf.

LG, Ferry
--
Ing. Ferry Bolhar
Municipality of Vienna, Department 14
A-1010 Vienna / AUSTRIA
E-mail: bol@adv.magwien.gv.at

Re: [Regex] Suchen nach Hex-Zeichen

am 27.06.2006 00:53:23 von hjp-usenet2

Ferry Bolhar wrote:
> Peter J. Holzer:
>> Mein lieber Ferry, Du gehst mir gewaltig auf den Zeiger!
>
> Das tut mir leid, es war nicht meine Absicht. Ich mag nur keine
> Ungenauigkeiten.
>
>> Die Werte 1234 und 5678 waren Beispiele.
>
> Und? Was wolltest du mit diesen Beispielen zeigen oder beweisen?

Das stand zwei Zeilen unterhalb der Zeile, die Du soeben zitiert hast.
Es stand auch in dem Posting, in dem ich das Beispiel gebracht habe.
Vielleicht liest Du einfach mal, was ich schreibe? Aber da wir hier
offensichtlich in einem Gedicht von Lewis Carrol sind, zum dritten mal:

Characters (also die Elemente, aus denen ein String besteht) sind
seit Perl 5.6 keine 8-Bit-Werte mehr (sondern Werte mit mindestens
32 Bit).

Siehe dazu auch perldoc Encode:

TERMINOLOGY


· character: a character in the range 0..(2**32-1) (or more). (What
Perl’s strings are made of.)

· byte: a character in the range 0..255 (A special case of a Perl char‐
acter.)

· octet: 8 bits of data, with ordinal values 0..255 (Term for bytes
passed to or from a non-Perl context, e.g. a disk file.)


>>> Wenn ich mir das so durchlese, glaube ich, dass wir aneinander vorbei-
>>> reden, weil du (zu) theoretisch und ich (zu) praktisch denke.
>>
>> Ich denke da durchaus praktisch. Das Wegabstrahieren von Eigenschaften
>> einer bestimmten Implementation hilft, korrekte und portable Programme
>> zu schreiben.
>
> Es ist nur in Diskussionen, wo es eben um diese Eigenschaften geht,
> wenig hilfreich.

Mir geht es aber eben nicht um *diese* Eigenschaften, sondern um andere.
Mir geht es darum, wie die Sprache Perl Strings behandelt, und nicht
darum, wie die Implementation "perl 5.8.7 auf CP/M 64bit" Strings intern
abspeichert.

> Wenn ich schreibe, dass auch in Perl 5.6 und 5.8 Strings normalerweise
> (wie mein Beispiel "hello") in Bytes abge- speichert werden,

.... dann ist das reichlich sinnlos, denn auf byte-adressierbaren
Architekturen wird letzten Endes alles als Bytes abgespeichert.

> hilft es nicht sehr, wenn du meinst, dass dies seit
> Perl 5.6 String in "logischen 32-Bit-Werten" geschieht.

Doch, das hilft dem Perl-Programmierer. Das ist etwas, was er wissen
muss.

"ha", "h\x{E4}", "h\x{20AC}"

sind alles Strings von 2 Zeichen Länge, length liefert in allen Fällen
2, substr($string, 1) liefert in jedem Fall einen String der Länge 1,
ord(substr($string, 1)) liefert die Werte 0x61, 0xE4, 0x20AC. Letzterer
Wert ist nicht in 8 Bit darstellbar. Es ist für den Perl-Programmierer
wichtig zu wissen, dass ord Werte zwischen 0 und 2**32-1 (und eventuell
noch mehr) liefern kann und chr diesen Range akzeptiert. Es ist für den
Perl-Programmierer auch wichtig zu wissen, dass es da so ein magisches
"is_utf8"-Flag gibt, das auf manche Stringfunktionen Einfluß hat (z.B.
matcht /\w$/ den zweiten String nur wenn dieses Flag gesetzt ist (oder
eine passende Locale geladen ist)).

Wie diese Strings nun exakt gespeichert werden, ist dem
Perl-Programmierer genauso egal wie Details zum Aufbau von Hashes.
Das interessiert nur den XS-Programmierer, weil der auf perl-interne
Datenstrukturen zugreifen muss, und daher wissen muss, wie sie aussehen.

("use bytes" habe ich in der Betrachtung vernachlässigt - das ist ein
anderes Kapitel)

> Was willst du damit aussagen? Wie sieht "hello" als "logischer 32-
> Bit-Wert" abgespeichert aus?

Quatsch. "hello" wird nicht "als logischer 32-Bit-Wert" gespeichert. Das
habe ich nie behauptet. Strings *bestehen aus* "logischen
32-Bit-Werten". So wie ein Haus aus Ziegelsteinen besteht und kein
Ziegelstein ist. (Mr. Ferry Nitpicker wird jetzt gleich einwerfen,
dass es auch Häuser aus Holz, Beton, und vielen anderen Materialien
gibt). Der String "hello" besteht aus 5 Elementen mit den numerischen
Werten (EBCDIC vernachlässige ich jetzt): 0x68, 0x65, 0x6C, 0x6C, 0x6F.
Der zulässige Bereich geht aber bis (mindestens) 0xFFFF_FFFF. So wie Du
in C in einem unsigned long eben jeden Wert von 0 bis mindestens
0xFFFFFFFF speichern kannst.


> Und wie ich auch geschrieben habe, gbit es eben Plattformen, auf
> denen ein IV 64 Bit umfasst. Gibt es dort dann "logische 64-Bit-
> Werte"?

Wie ich auch (mehrfach!) geschrieben habe: Möglich, aber das wird von
der Dokumentation nicht zugesichert. Dort ist nur von mindestens 32 Bit
die Rede. Ich kann mich darauf verlassen, dass "\x{FFFFFFFF}" ein
gültiger String der Länge 1 ist, der auf allen Perl 5.8-Implementationen
verwendet werden kann. Ich kann mich nicht darauf verlassen,
dass das bei "\x{FFFFFFFFFFFFFFFF}" der Fall ist. Tatsächlich halte ich
es (wie ich auch schon mehrfach geschrieben habe) für unwahrscheinlich,
dass es derzeit Perl-Implementationen mit 64-Bit-Characters gibt, weil
sich das mit UTF-8 einfach nicht ausgeht und diese Implementationen dann
eine andere Methode als UTF-8 bräuchten, und der Nutzen wohl den Aufwand
nicht rechtfertigt. Und schließlich habe ich ebenfalls bereits darauf
hingewiesen dass die Länge eines IV nichts mit der Länge eines
Characters zu tun hat.

> Aber bevor ich dir noch mehr "auf den Zeiger gehe", höre ich
> lieber auf.

Ich höre nach diesem Posting bestimmt auf. Wenn ich nur mehr Sachen
wiederhole, die ich vorher schon geschrieben habe, dann tendiert der
Informationsgehalt des Postings gegen Null.

hp

PS: http://www.literature.org/authors/carroll-lewis/the-hunting- of-the-snark/

--
_ | Peter J. Holzer | Man könnte sich [die Diskussion] auch
|_|_) | Sysadmin WSR/LUGA | sparen, wenn man sie sich einfach sparen
| | | hjp@hjp.at | würde.
__/ | http://www.hjp.at/ | -- Ralph Angenendt in dang 2006-04-15

Re: [Regex] Suchen nach Hex-Zeichen

am 27.06.2006 08:10:09 von Slaven Rezic

"Peter J. Holzer" writes:

[...]>
>
> "ha", "h\x{E4}", "h\x{20AC}"
>
> sind alles Strings von 2 Zeichen Länge, length liefert in allen Fällen
> 2, substr($string, 1) liefert in jedem Fall einen String der Länge 1,
> ord(substr($string, 1)) liefert die Werte 0x61, 0xE4, 0x20AC. Letzterer
> Wert ist nicht in 8 Bit darstellbar.


Doch, wenn man das passende Encoding (iso-8859-15 oder
Windows-irgendwas) verwendet.


--
Slaven Rezic - slaven rezic de

Berlin Perl Mongers - http://berlin.pm.org

Re: [Regex] Suchen nach Hex-Zeichen

am 27.06.2006 09:23:34 von Ferry Bolhar

Peter J. Holzer:

> Characters (also die Elemente, aus denen ein String besteht) sind
> seit Perl 5.6 keine 8-Bit-Werte mehr (sondern Werte mit mindestens
> 32 Bit).

Und das ist eben falsch, wie ich mit meinem "Hello"-Beispiel bewiesen
habe. Vielleicht liest du mal, was ich schreibe?

Dem obigen Satz ist zu entnehmen, dass ein String wie "Hello", der aus
Charaktern besteht, die ihrerseits Werte mit mindestens 32 Bit sind, in
5 Longwords abgespeichert werden muss (weil die Werte ja mindestens
32-Bit groß sind). Und das ist definitiv auch in Perl 5.6 und 5.8 nicht
der Fall.

Es _mag_ sein, dass ein String auch Charakters enthalten kann, die
_bis_ zu 32 Bit groß sein können. Es _muss_ aber nicht sein. Es gibt
keine _Mindest_größe von 32 Bit. Und genau das behauptest du.
Wenn du statt "mindestens 32 Bit" besser "bis zu 32 Bit" geschrieben
hättest, wäre es richtiger gewesen.

"Hello" wird mit 5 Characters in 5 Bytes + einen Nullbyte abge-
speichert. Daran hat sich nichts geändert. Dass ord() u.a. jetzt
auch 32-Bit-Werte akzeptiert, ist richtig und das habe ich auch
nicht bestritten. Das ist einfach eine Erweiterung des Wertbereiches,
die eben durch die neue _mögliche_ Maximalgröße eines Charakters
begründet ist. Aber deswegen sind die meisten Charakters eines
Strings in einem Perl-Programm nach wie vor 8-Bit-Werte (also
*besteht* der String als solchen Characters) und die "Mindestgröße",
wenn man überhaupt von einer solchen sprechen will, ist daher nach
wie vor 8 Bit.

> Siehe dazu auch perldoc Encode:
>
> TERMINOLOGY
>
> · character: a character in the range 0..(2**32-1) (or more).
(What
> Perl's strings are made of.)
>
> · byte: a character in the range 0..255 (A special case of a Perl
char-
> acter.)

Ja, wobei in 99.9% aller Perlprogramme dieser "special case" gegeben
ist. und auch noch lange gegeben sein wird. Ich halte diese Definition für
nicht sehr glücklich; zumindest momentan (und wohl auch noch einige
Zeit) werden Charakters mit Werten > 256 eher der "special case" sein.
Aber bitte, das ist halt schon eine sehr zukunftsorientierte Definition.
Man sollte aber deswegen die derzeitigen Implementierungen nicht aus
den Augen verlieren (und um die ging es ja).

> > Wenn ich schreibe, dass auch in Perl 5.6 und 5.8 Strings normalerweise
> > (wie mein Beispiel "hello") in Bytes abge- speichert werden,
>
> ... dann ist das reichlich sinnlos, denn auf byte-adressierbaren
> Architekturen wird letzten Endes alles als Bytes abgespeichert.

Es zeigt nur, dass deine Definition von Charakters, die "seit Perl 5.6
eine Größe von mindestens 32 Bit haben", falsch ist.

> Wie diese Strings nun exakt gespeichert werden, ist dem
> Perl-Programmierer genauso egal wie Details zum Aufbau von Hashes.
> Das interessiert nur den XS-Programmierer, weil der auf perl-interne
> Datenstrukturen zugreifen muss, und daher wissen muss, wie sie aussehen.

Damit bist du bei mir an der falschen Adresse, denn die Frage nach der
Art und Weise, wie Werte wie \x{20AC}abgespeichert werden und
damit generell der Speicherbedarf zum Abspeichern von Strings, kam
nicht von mir. Vielleicht interessiert es eben doch mehr als du denkst...

> Quatsch. "hello" wird nicht "als logischer 32-Bit-Wert" gespeichert. Das
> habe ich nie behauptet.

Doch. "hello" ist ein String, Strings bestehen aus Characters und deren
Werte sind _mindestens_ 32 Bit groß. Das hast du behauptet (siehe
Anfang) und das ist, ganz richtig, Quatsch.

> Strings *bestehen aus* "logischen 32-Bit-Werten".

Noch einmal: was ist ein "logischer 32-Bit-Wert"? Was ist ein "nicht-
logischer" 32-Bit Wert? Warum schreibst du nicht einfach, dass die
Characters eines Strings ab Perl 5.6. _bis_ zu 32-Bit groß werden
können? Was soll dieses Jonglieren mit solchen abstrakten Begriffen?
Schreib doch einfach, wie es wirklich ist, und was Perl tut: Strings
*bestehen* aus Characters, die seit 5.6_auch_ größer als 8-Bit sein
_können_ (_bis zu_ 32 Bit). Characters, die in 8-Bit passen, werden
aber wie bisher in einem Byte abgespeichert, für die anderen werden
zwei und mehr Bytes verwendet (no na).

Ich kann mit deiner Definition von "logischen Werten" nichts anfangen
und sehe auch keinen Nutzen dahinter. Sie wirkt höchstens verwirrend,
weil sie eben zum Schluß führt, dass auf Grund der "Mindestgröße von
32 Bit" tatsächlich für jedes Zeichen ein Longword zum Kodieren und
Abspeichern verwendet wird, denn wenn ein String aus "Werten mit
einer Mindestgröße von 32 Bit *besteht*, dann muss er ja wohl auch
(wenn nicht gerade ein Komprimierungsverfahren verwendet wird) mit
diesen 32-Bit-Werten *abgespeichert* werden, oder nicht?

> Dort ist nur von mindestens 32 Bit
> die Rede. Ich kann mich darauf verlassen, dass "\x{FFFFFFFF}" ein
> gültiger String der Länge 1 ist, der auf allen Perl 5.8-Implementationen
> verwendet werden kann.

5.8? Nicht 5.6? Weiter oben hast du noch von 5.6 gesprochen.

> Ich höre nach diesem Posting bestimmt auf. Wenn ich nur mehr Sachen
> wiederhole, die ich vorher schon geschrieben habe, dann tendiert der
> Informationsgehalt des Postings gegen Null.

Ja. Und nur weil du sie immer wiederholst, werden sie deswegen nicht
richtiger oder verständlicher.

Ich würde vorschlagen, unsere Unterhaltung vielleicht privat fortzusetzen.
Meine E-Mail-Adresse findest du in meiner Signatur.

LG, Ferry

--
Ing. Ferry Bolhar
Municipality of Vienna, Department 14
A-1010 Vienna / AUSTRIA
E-mail: bol@adv.magwien.gv.at

Re: [Regex] Suchen nach Hex-Zeichen

am 27.06.2006 11:16:44 von hjp-usenet2

Slaven Rezic wrote:

> "Peter J. Holzer" writes:
>
> [...]>
>>
>> "ha", "h\x{E4}", "h\x{20AC}"
>>
>> sind alles Strings von 2 Zeichen Länge, length liefert in allen Fällen
>> 2, substr($string, 1) liefert in jedem Fall einen String der Länge 1,
>> ord(substr($string, 1)) liefert die Werte 0x61, 0xE4, 0x20AC. Letzterer
>> Wert ist nicht in 8 Bit darstellbar.
>
>
> Doch, wenn man das passende Encoding (iso-8859-15 oder
> Windows-irgendwas) verwendet.
>



Dann ist es aber nicht mehr der Wert 0x20AC sondern der Wert 0xA4 oder
0x80 oder so.


Prinzipiell hast Du natürlich recht. Von einem einzelnen Wert kann man
nie sagen. wieviele Bits man braucht, um ihn auszudrücken, wenn das
Kodierungsschema nicht schon vorgegeben ist. Das kann man immer nur von
einer Menge von Werten sagen. In meinen Strings oben kommen nur 4
verschiedene Zeichen vor, also reichen theoretisch 2 Bits pro Zeichen,
um sie darzustellen. Richtiger hätte ich schreiben müssen "0x20AC ist
nicht als 8-stellige Binärzahl darstellbar" (damit wäre das
Kodierungsschema klar gewesen) oder "es gibt kein Kodierungsschema, das
alle Werte von 0 bis 0x20AC in 8 Bit kodieren kann". Gemeint war eher
letzteres, aber wenn ich weiß nicht, ob es wesentlich klarer gewesen
wäre, wenn ich das so geschrieben hätte.

hp

--
_ | Peter J. Holzer | Man könnte sich [die Diskussion] auch
|_|_) | Sysadmin WSR/LUGA | sparen, wenn man sie sich einfach sparen
| | | hjp@hjp.at | würde.
__/ | http://www.hjp.at/ | -- Ralph Angenendt in dang 2006-04-15

Re: [Regex] Suchen nach Hex-Zeichen

am 27.06.2006 20:44:15 von Slaven Rezic

"Ferry Bolhar" writes:

> Peter J. Holzer:
>
> > Characters (also die Elemente, aus denen ein String besteht) sind
> > seit Perl 5.6 keine 8-Bit-Werte mehr (sondern Werte mit mindestens
> > 32 Bit).
>
> Und das ist eben falsch, wie ich mit meinem "Hello"-Beispiel bewiesen
> habe. Vielleicht liest du mal, was ich schreibe?

Ferry, ich glaube, du hast die Philosophie hinter der
Unicode-Implementation in Perl nicht verstanden.

>
> Dem obigen Satz ist zu entnehmen, dass ein String wie "Hello", der aus
> Charaktern besteht, die ihrerseits Werte mit mindestens 32 Bit sind, in
> 5 Longwords abgespeichert werden muss (weil die Werte ja mindestens
> 32-Bit groß sind). Und das ist definitiv auch in Perl 5.6 und 5.8 nicht
> der Fall.

Nein. Bitte lese dir noch einmal die Terminologie in Encode.pod
bezüglich byte/octets vs. characters durch. Auch wenn du diese
Terminologie für nicht glücklich hältst (aus Gründen, die falsch sind,
und die ich noch widerlegen werde), wir müssen uns bei der Diskussion
auf etwas einigen. Characters sind Dinge, die 32 Bit groß sind (und
womöglich noch größer werden/sein können).

>
> Es _mag_ sein, dass ein String auch Charakters enthalten kann, die
> _bis_ zu 32 Bit groß sein können. Es _muss_ aber nicht sein. Es gibt
> keine _Mindest_größe von 32 Bit. Und genau das behauptest du.
> Wenn du statt "mindestens 32 Bit" besser "bis zu 32 Bit" geschrieben
> hättest, wäre es richtiger gewesen.

Nun, es gibt auch Characters, die auch mit einem Bit dargestellt
werden können. Und ich glaube, das würdest du auch nicht als
"Mindestgröße" akzeptieren.

>
> "Hello" wird mit 5 Characters in 5 Bytes + einen Nullbyte abge-
> speichert. Daran hat sich nichts geändert.

Du hast in die Interna von Perl geschaut. Gut, so sieht ein String
intern tatsächlich aus. Konzeptionell spricht aber nichts dagegen,
dass man diesen String auch in 20 Bytes abspeichern könnte (z.B. wenn
Perl als internes Encoding UCS-4 wählen würde).

> Dass ord() u.a. jetzt
> auch 32-Bit-Werte akzeptiert, ist richtig und das habe ich auch
> nicht bestritten. Das ist einfach eine Erweiterung des Wertbereiches,
> die eben durch die neue _mögliche_ Maximalgröße eines Charakters
> begründet ist. Aber deswegen sind die meisten Charakters eines
> Strings in einem Perl-Programm nach wie vor 8-Bit-Werte (also
> *besteht* der String als solchen Characters) und die "Mindestgröße",
> wenn man überhaupt von einer solchen sprechen will, ist daher nach
> wie vor 8 Bit.

Die meisten Characters *eines* Strings? Du meinst die meisten
Characters in *deinen* Strings. Jemand aus dem CJK-Raum würde dir
vehement widersprechen.

>
> > Siehe dazu auch perldoc Encode:
> >
> > TERMINOLOGY
> >
> > · character: a character in the range 0..(2**32-1) (or more).
> (What
> > Perl's strings are made of.)
> >
> > · byte: a character in the range 0..255 (A special case of a Perl
> char-
> > acter.)
>
> Ja, wobei in 99.9% aller Perlprogramme dieser "special case" gegeben
> ist. und auch noch lange gegeben sein wird. Ich halte diese Definition für
> nicht sehr glücklich; zumindest momentan (und wohl auch noch einige
> Zeit) werden Charakters mit Werten > 256 eher der "special case" sein.
> Aber bitte, das ist halt schon eine sehr zukunftsorientierte Definition.
> Man sollte aber deswegen die derzeitigen Implementierungen nicht aus
> den Augen verlieren (und um die ging es ja).

Wie gesagt, das ist deine enge, auf westeuropäische Sprachen und
Schriften bezogene Ansicht.

>
> > > Wenn ich schreibe, dass auch in Perl 5.6 und 5.8 Strings normalerweise
> > > (wie mein Beispiel "hello") in Bytes abge- speichert werden,
> >
> > ... dann ist das reichlich sinnlos, denn auf byte-adressierbaren
> > Architekturen wird letzten Endes alles als Bytes abgespeichert.
>
> Es zeigt nur, dass deine Definition von Charakters, die "seit Perl 5.6
> eine Größe von mindestens 32 Bit haben", falsch ist.

Ich hatte schonmal in diesem Thread (oder einem Vorgängerthread)
geschrieben, dass ich die Verwendung von "Bit" in diesem Zusammenhang
für nicht glücklich halte, weil man damit Maschinennähe suggeriert.
Peter meint wohl tatsächlich nur den Wertebereich, nicht, wie
Characters tatsächlich in der Maschine gespeichert werden.

[...]
>
> > Strings *bestehen aus* "logischen 32-Bit-Werten".
>
> Noch einmal: was ist ein "logischer 32-Bit-Wert"? Was ist ein "nicht-
> logischer" 32-Bit Wert? Warum schreibst du nicht einfach, dass die
> Characters eines Strings ab Perl 5.6. _bis_ zu 32-Bit groß werden
> können? Was soll dieses Jonglieren mit solchen abstrakten Begriffen?
> Schreib doch einfach, wie es wirklich ist, und was Perl tut: Strings
> *bestehen* aus Characters, die seit 5.6_auch_ größer als 8-Bit sein
> _können_ (_bis zu_ 32 Bit). Characters, die in 8-Bit passen, werden
> aber wie bisher in einem Byte abgespeichert, für die anderen werden
> zwei und mehr Bytes verwendet (no na).

Auch das stimmt nicht ganz. Für den Bereich zwischen 128 und 255 gibt
es in Perl zwei Arten, ein Zeichen zu kodieren: die alte Art ohne
UTF8-Flag (damit passen diese Zeichen in ein Byte), oder mit
UTF8-Flag, womit sie in zwei Bytes gespeichert werden.

Wie es tatsächlich intern aussieht, sollte dir als normaler
Perl-Programmierer egal sein.

>
> Ich kann mit deiner Definition von "logischen Werten" nichts anfangen
> und sehe auch keinen Nutzen dahinter. Sie wirkt höchstens verwirrend,
> weil sie eben zum Schluß führt, dass auf Grund der "Mindestgröße von
> 32 Bit" tatsächlich für jedes Zeichen ein Longword zum Kodieren und
> Abspeichern verwendet wird, denn wenn ein String aus "Werten mit
> einer Mindestgröße von 32 Bit *besteht*, dann muss er ja wohl auch
> (wenn nicht gerade ein Komprimierungsverfahren verwendet wird) mit
> diesen 32-Bit-Werten *abgespeichert* werden, oder nicht?

Rate mal, was UTF-8 ist. Das ist ein recht ausgeklügeltes Encoding.
Für die Codepoints 0 .. 127 ist es identisch zu ASCII, so kann im
englischsprachigen Raum UTF-8 ohne (größere) Anpassungen verwendet
werden. Es ist aber auch eine Art "Huffman coding": Zeichen, die
häufiger vorkommen, werden mit weniger Bytes kodiert, seltener
vorkommende Zeichen werden mit mehr Bytes kodiert. Man kann also UTF-8
durchaus als Komprimierungsverfahren für 32-Bit-Werte verwenden, wenn
die kleineren Werte häufiger vorkommen.

>
> > Dort ist nur von mindestens 32 Bit
> > die Rede. Ich kann mich darauf verlassen, dass "\x{FFFFFFFF}" ein
> > gültiger String der Länge 1 ist, der auf allen Perl 5.8-Implementationen
> > verwendet werden kann.
>
> 5.8? Nicht 5.6? Weiter oben hast du noch von 5.6 gesprochen.

Naja, das Unicode-Modell von Perl 5.6 kann man ruhig vergessen. Wir
brauchen wirklich nur über Perl 5.8 sprechen.

>
> > Ich höre nach diesem Posting bestimmt auf. Wenn ich nur mehr Sachen
> > wiederhole, die ich vorher schon geschrieben habe, dann tendiert der
> > Informationsgehalt des Postings gegen Null.
>
> Ja. Und nur weil du sie immer wiederholst, werden sie deswegen nicht
> richtiger oder verständlicher.
>
> Ich würde vorschlagen, unsere Unterhaltung vielleicht privat fortzusetzen.
> Meine E-Mail-Adresse findest du in meiner Signatur.
>

Das habe ich einfach ignoriert, ich wollte auch meinen Senf dazugeben.

Gruß,
Slaven

--
Slaven Rezic - slaven rezic de
Tired of using file selectors? Real programmers use the TAB key for
completion and not for jumping around. Try
http://search.cpan.org/search?mode=module&query=Tk::PathEntr y

Re: [Regex] Suchen nach Hex-Zeichen

am 27.06.2006 22:50:46 von Frank Seitz

Slaven Rezic wrote:

> Nein. Bitte lese dir noch einmal die Terminologie in Encode.pod
> bezüglich byte/octets vs. characters durch. Auch wenn du diese
> Terminologie für nicht glücklich hältst (aus Gründen, die falsch sind,
> und die ich noch widerlegen werde), wir müssen uns bei der Diskussion
> auf etwas einigen. Characters sind Dinge, die 32 Bit groß sind (und
> womöglich noch größer werden/sein können).

Die Zahl 32 kommt in Encode.pod genau einmal vor, in der
Definition des Zeichens:

character: a character in the range 0..(2**32-1) (or more). (What
Perl's strings are made of.)

Diese Definition finde ich dunkel, da sie zyklisch ist. Was ein
Zeichen ist, erschließt sich mir daraus nicht.
Und warum es für die Logik der Sache wichtig sein soll,
wie groß der Zeichenvorrat ist - worüber hier so heiß
diskutiert wird - erschließt sich mir auch nicht.

Ich habe das Gefühl, alle haben die Sache mit den Zeichenketten
in Perl irgendwie verstanden, aber die Betrachtungsebenen
(Logische Ebene, Implementierungsebene) und die dazugehörigen Begriffe
(Zeichen, Zeichensatz, Position eines Zeichens in einem Zeichensatz,
Encoding eines Zeichensatzes, usw.) sind den Beteiligten
nicht so sonnenklar bzw. gehen in der Diskussion durcheinander.

Mir geht es wie Ferry. Ich find die ursprüngliche Aussage,
ein String in Perl sei eine Folge von 32-Bit-Werten, sehr schief.
Das klingt wie die missverständliche Wiedergabe obiger
Definition, die - wie gesagt - meiner Meinung nach für sich genommen
schon einige Probleme hat.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: [Regex] Suchen nach Hex-Zeichen

am 27.06.2006 23:33:42 von Slaven Rezic

Frank Seitz writes:

> Slaven Rezic wrote:
>
> > Nein. Bitte lese dir noch einmal die Terminologie in Encode.pod
> > bezüglich byte/octets vs. characters durch. Auch wenn du diese
> > Terminologie für nicht glücklich hältst (aus Gründen, die falsch sind,
> > und die ich noch widerlegen werde), wir müssen uns bei der Diskussion
> > auf etwas einigen. Characters sind Dinge, die 32 Bit groß sind (und
> > womöglich noch größer werden/sein können).
>
> Die Zahl 32 kommt in Encode.pod genau einmal vor, in der
> Definition des Zeichens:
>
> character: a character in the range 0..(2**32-1) (or more). (What
> Perl's strings are made of.)
>
> Diese Definition finde ich dunkel, da sie zyklisch ist. Was ein
> Zeichen ist, erschließt sich mir daraus nicht.

Eindeutiger wäre vielleicht:

| Perl character: a Unicode character ...

Aber mir ist bislang niemals, aufgefallen, dass die Definition
zyklisch ist :-)

> Und warum es für die Logik der Sache wichtig sein soll,
> wie groß der Zeichenvorrat ist - worüber hier so heiß
> diskutiert wird - erschließt sich mir auch nicht.

Wichtig ist hervorzuheben, dass es mehr als 8 Bit --- bei uns allen
steckt noch die Gleichung 8 Bit = 1 Byte = 1 Zeichen im Blut.

>
> Ich habe das Gefühl, alle haben die Sache mit den Zeichenketten
> in Perl irgendwie verstanden, aber die Betrachtungsebenen
> (Logische Ebene, Implementierungsebene) und die dazugehörigen Begriffe
> (Zeichen, Zeichensatz, Position eines Zeichens in einem Zeichensatz,
> Encoding eines Zeichensatzes, usw.) sind den Beteiligten
> nicht so sonnenklar bzw. gehen in der Diskussion durcheinander.

Mir ist es schon ziemlich klar!

> Mir geht es wie Ferry. Ich find die ursprüngliche Aussage,
> ein String in Perl sei eine Folge von 32-Bit-Werten, sehr schief.
> Das klingt wie die missverständliche Wiedergabe obiger
> Definition, die - wie gesagt - meiner Meinung nach für sich genommen
> schon einige Probleme hat.

Dann ist also für dich ein Perl-String eine Folge von 8-Bit-Werten?
Oder einfach eine Folge von Zeichen? Aber war ist ein Zeichen in Perl?
Ein Ding, das als maximalen Wert 2**32 annehmen kann? Dann sind wir
wieder bei der obigen Definition (auch wenn sie besser ausgedrückt
werden kann).

Gruß,
Slaven

--
Slaven Rezic - slaven rezic de

Lost in your Tk widget tree? Try
http://user.cs.tu-berlin.de/~eserte/src/perl/Tk-WidgetDump/

Re: [Regex] Suchen nach Hex-Zeichen

am 28.06.2006 09:12:12 von Frank Seitz

Slaven Rezic wrote:
> Frank Seitz writes:
>>
>>Ich habe das Gefühl, alle haben die Sache mit den Zeichenketten
>>in Perl irgendwie verstanden, aber die Betrachtungsebenen
>>(Logische Ebene, Implementierungsebene) und die dazugehörigen Begriffe
>>(Zeichen, Zeichensatz, Position eines Zeichens in einem Zeichensatz,
>>Encoding eines Zeichensatzes, usw.) sind den Beteiligten
>>nicht so sonnenklar bzw. gehen in der Diskussion durcheinander.
>
> Mir ist es schon ziemlich klar!

Glaube ich Dir. Du hast Dich von uns hier mit Sicherheit am meisten
damit beschäftigt, das geht aus Deinen Postings hervor.
Andererseits fragst Du mich - siehe unten - was ein Zeichen in Perl ist.
ALLES scheint Dir also doch nicht so sonnenklar zu sein :)

>>Mir geht es wie Ferry. Ich find die ursprüngliche Aussage,
>>ein String in Perl sei eine Folge von 32-Bit-Werten, sehr schief.
>>Das klingt wie die missverständliche Wiedergabe obiger
>>Definition, die - wie gesagt - meiner Meinung nach für sich genommen
>>schon einige Probleme hat.
>
> Dann ist also für dich ein Perl-String eine Folge von 8-Bit-Werten?
> Oder einfach eine Folge von Zeichen? Aber war ist ein Zeichen in Perl?
> Ein Ding, das als maximalen Wert 2**32 annehmen kann? Dann sind wir
> wieder bei der obigen Definition (auch wenn sie besser ausgedrückt
> werden kann).

Ich definiere mal einige Begriffe, wie ich sie verstehe:

Zeichen: Ein Schriftsymbol, grafisches Symbol etc.
Sowas wie "der große Buchstabe A" oder "das Eurosymbol" oder "das
chinesische Schriftzeichen für ichweißnichtwas". Zeichen
kommen in Programmiersprachen direkt nicht vor, sondern nur
Repräsentationen von Zeichen.

Zeichenkette: Eine Abfolge von Zeichen.

Zeichensatz: Eine Menge von Zeichen mit einer festglegten Ordnung.
Beispiele sind ASCII, ISO-8859-1 oder Unicode.
Da in einem Zeichensatz die Reihenfolge der Zeichen festgelegt ist,
ist jedes Zeichen innerhalb des Zeichensatzes durch seine
Postionsnummer eindeuteutig bestimmt.
Die Positionsnummer IST aber nicht das Zeichen. Denn ein und
dasselbe Zeichen kann in verschiedenen Zeichensätzen
verschiedene Postionsnummern haben.

Encoding: Festlegung darüber, wie die Zeichen eines Zeichensatzes,
in Bits und Bytes repräsentiert sind. Beispiel: UTF-8 für Unicode.
Während die Begriffe "Zeichen" und "Zeichensatz" die
logisch-abstrakte Ebene betreffen - unabhängig von einem
zeichenverarbeitenden System -, schlägt das Encoding die Brücke zum
Konkreten, also wie die Zeichen (und damit
Zeichenketten über diesem Zeichensatz) in einem solchen System -
von denen Perl eins ist - konkret repräsentiert sind.
Wenn davon die Rede ist, in Perl sei ein Zeichen oder eine Zeichenkette
das-und-das, verstehe ich das als eine Aussage über die
Repräsentationsebene oder etwas, was da ziemlich nah dran liegt.

Nun nochmal der strittige Satz:

Ein String (eine Zeichenkette) ist in Perl eine Folge von 32-Bit-Werten.

Wenn ich obige Definitionen zugrunde lege und anwende,
komme ich zu dem Ergebnis, dass der Satz unrettbar schräg bis falsch ist.
Ich will meine Sicht nicht als die alleeinseligmachende hinstellen.
Die Kritik kann ich aber nachvollziehen.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: [Regex] Suchen nach Hex-Zeichen

am 29.06.2006 17:30:59 von hjp-usenet2

Frank Seitz wrote:
> Slaven Rezic wrote:
>> Nein. Bitte lese dir noch einmal die Terminologie in Encode.pod
>> bezüglich byte/octets vs. characters durch. Auch wenn du diese
>> Terminologie für nicht glücklich hältst (aus Gründen, die falsch sind,
>> und die ich noch widerlegen werde), wir müssen uns bei der Diskussion
>> auf etwas einigen. Characters sind Dinge, die 32 Bit groß sind (und
>> womöglich noch größer werden/sein können).
>
> Die Zahl 32 kommt in Encode.pod genau einmal vor, in der
> Definition des Zeichens:
>
> character: a character in the range 0..(2**32-1) (or more). (What
> Perl's strings are made of.)
>
> Diese Definition finde ich dunkel, da sie zyklisch ist.

Ja, die ist missglückt.

Da jeder eine Vorstellung hat, was ein "Zeichen" zu sein hat, nenne ich
die Dinger, aus denen ein Perl-String besteht, einfach "Pflurfls"
(Google findet das Wort nicht, also mache ich mir berechtigte
Hoffnungen, dass es niemand kennt und damit irgendwas verbindet). Was
ein Pflurfl ist, wissen wir mal vorerst nicht, aber wir kennen
verschiedene Eigenschaften:

* Es gibt N verschiedene Pflurfls, wobei N mindestens 2**32 ist.

* Es gibt eine bijektive Abbildung von Pflurfls auf die nicht-negativen
ganzen Zahlen von 0 .. N-1, d.h. jedem Pflurfl ist eine Nummer in
diesem Bereich eineindeutig zugeordnet.

Man benötigt somit log2(N) Bits um ein Pflurfl eindeutig zu
identifizieren, somit kann man einen String als Folge von
log2(N)-Bit-Werten sehen. Das ist die Aussage des Satzes "Ein String in
Perl ist eine Folge von 32-Bit-Werten", der Dir und Ferry offenbar so
viel Kopfzerbrechen bereitet. Das ist eine Aussage über den
Wertebereich, keine Aussage über die Speicherverbrauch in einer
bestimmten Implementation.

* Ein Pflurfl hat von vornherein keine Semantik. Er ist kein "Zeichen".
Nichts in Perl erzwingt, dass der String "\x{70}\x{61}" die Folge der
beiden Zeichen LATIN SMALL LETTER P und LATIN SMALL LETTER A ist.
Tatsächlich habe ich den gerade einem PNG-File entnommen und es sind
wohl einfach nur 16 Bit aus einer komprimierten Folge von
RGB-Amplitudenwerten. Die Semantik eines Perl-Strings ergibt sich
ausschließlich aus dem Perl-Programm, in dem er verwendet wird. Viele
Perl-Strings sind Folgen von Zeichen, manche sind Folgen von Octets,
aber im Prinzip kann jeder Datentyp, der sich auf eine Teilmenge von
0..N abbilden läßt, in einem Perl-Programm als Pflurfl repräsentiert
werden.

* Die bitweisen Operatoren &, |, ^ sind auf Strings definiert und
arbeiten mit den numerischen Werten der Pflurfls.

Somit sind bis hierher die Pflurfls tatsächlich nur Bitmuster mit
mindestens 32 Bit. Jetzt kommen wir zu den Zeichen.

Unter einem "coded character set" versteht man eine Menge von Zeichen,
wobei jedem Zeichen eine (nicht-negative) ganze Zahl zugeordnet ist.
Davon gibt es viele, z.B. ASCII, die diversen ISO-8859-* Zeichensätze,
ISO-10646, etc.

* Es gibt einige Funktionen und Operatoren in Perl, die annehmen, dass
ein Pflurfl einem Zeichen in einem bestimmten coded character set
entspricht. dazu gehören z.B. regexp matches und substitutes, uc und
lc.

* Dieses coded character set hängt vom zu bearbeitenden String (ist das
utf8-Flag gesetzt?) und der Locale ab.

Es liegt in der Verantwortung des Programmierers, diese Funktionen
richtig zu verwenden. Wendet er uc auf einen String an, dessen Pflurfls
nicht tatsächlich Zeichen in der current locale darstellen, so
produziert er Unsinn, genauso wie wenn er unpack 'N*' auf einen String
anwendet, dessen Pflurfls nicht Oktets darstellen, die 32-Bit-Werte in
Network Byte Order kodieren. Perl unterscheidet das nicht, für Perl ist
jeder String einfach eine Folge von Pflurfls.

(unter Umständen wäre es in dieser Betrachtung sinnvoll, Strings mit und
ohne utf8-Flag zu trennen, so wie es in bestimmten Kontext sinnvoll ist,
Strings von Floating-Point-Werten und die von Integers zu trennen,
obwohl für Perl alles nur Skalare sind)

> Was ein Zeichen ist, erschließt sich mir daraus nicht.
> Und warum es für die Logik der Sache wichtig sein soll,
> wie groß der Zeichenvorrat ist - worüber hier so heiß
> diskutiert wird - erschließt sich mir auch nicht.

Wie groß er genau ist, ist nicht so wichtig, aber es ist wichtig, dass
er größer als 256 ist - das bricht nämlich die Äquivalenz Octet = byte =
Character, die viele von uns im Hirn haben.


> Ich habe das Gefühl, alle haben die Sache mit den Zeichenketten
> in Perl irgendwie verstanden,

Das Gefühl habe ich nicht.

hp

--
_ | Peter J. Holzer | > Wieso sollte man etwas erfinden was nicht
|_|_) | Sysadmin WSR | > ist?
| | | hjp@hjp.at | Was sonst w�e der Sinn des Erfindens?
__/ | http://www.hjp.at/ | -- P. Einstein u. V. Gringmuth in desd

Re: [Regex] Suchen nach Hex-Zeichen

am 03.07.2006 10:12:45 von Ferry Bolhar

Peter J. Holzer:

"
> Da jeder eine Vorstellung hat, was ein "Zeichen" zu sein hat, nenne ich
> die Dinger, aus denen ein Perl-String besteht, einfach "Pflurfls"
> (Google findet das Wort nicht, also mache ich mir berechtigte
> Hoffnungen, dass es niemand kennt und damit irgendwas verbindet). Was
> ein Pflurfl ist, wissen wir mal vorerst nicht, aber wir kennen
> verschiedene Eigenschaften:

[...]

Danke für diese ausführliche Erklärung. Jetzt ist auch mir klar, was
gemeint ist... ;-)

Übrig bleibt die IMHO ziemlich verwirrende Definition

"Ein String in Perl ist eine Folge von 32-Bit-Werten"

die mit deiner Erklärung

> Man benötigt somit log2(N) Bits um ein Pflurfl eindeutig zu
> identifizieren, somit kann man einen String als Folge von
> log2(N)-Bit-Werten sehen.

doch um einiges anders aussieht.

Ich gebe auch zu, dass bei mir die Vorstellung Zeichen = Byte
immer noch sehr tief verankert ist, wenngleich mir klar ist, dass
diese Zeiten bald vorbei sein werden (bzw. teilweise schon sind).

Der theoretische "Wertbereich" eines Pflurls liegt bei 32 Bit.
Praktisch werden zumindest ASCII-Zeichen immer noch in
8 Bit abgespeichert.

Mr ging es nur darum zu zeigen, dass dies auch noch in Perl 5.6
und 5.8 der Fall ist. Deiner Aussage zufolge, "seit Perl 5.6 ist ein
String eine Folge von 32-Bit-Werten", hätte man ohne der jetzt
erfolgten Klarstellung etwas anderes annehmen können.

LG, Ferry

--
Ing. Ferry Bolhar
Municipality of Vienna, Department 14
A-1010 Vienna / AUSTRIA
E-mail: bol@adv.magwien.gv.at

Re: [Regex] Suchen nach Hex-Zeichen

am 03.07.2006 21:58:08 von Slaven Rezic

"Ferry Bolhar" writes:

[...]
>
> Ich gebe auch zu, dass bei mir die Vorstellung Zeichen = Byte
> immer noch sehr tief verankert ist, wenngleich mir klar ist, dass
> diese Zeiten bald vorbei sein werden (bzw. teilweise schon sind).
>
> Der theoretische "Wertbereich" eines Pflurls liegt bei 32 Bit.
> Praktisch werden zumindest ASCII-Zeichen immer noch in
> 8 Bit abgespeichert.

Vorsicht, jetzt wird es wieder ungenau. Was meinst du genau mit
"ASCII-Zeichen"? Die Unicode Map/das Encoding ascii (früher hat man
dafür "charset" gesagt)? Oder ein Unicode-Zeichen, das im
Codepoint-Bereich 0..127 vorkommt? Beachte, dass man solche
Unicode-Zeichen durchaus mit zwei oder mehr Bytes speichern kann, wenn
man als Encoding beispielsweise UCS-4 oder UTF-16 wählt.

Gruß,
Slaven

--
Slaven Rezic - slaven rezic de

Visualize Makefiles with GraphViz:
http://user.cs.tu-berlin.de/~eserte/src/perl/GraphViz-Makefi le/

Re: [Regex] Suchen nach Hex-Zeichen

am 04.07.2006 10:53:16 von Ferry Bolhar

Slaven Rezic:

>> Der theoretische "Wertbereich" eines Pflurls liegt bei 32 Bit.
>> Praktisch werden zumindest ASCII-Zeichen immer noch in
>> 8 Bit abgespeichert.
>
> Vorsicht, jetzt wird es wieder ungenau. Was meinst du genau mit
> "ASCII-Zeichen"?

Damit meine ich zB., dass damit ein 'A' in einem Byte, und zwar
als hex 41, abgespeichert wird. Oder der String "hello" als hex
68-65-6C-6C-6F-00, in 6 Bytes (mit dem Nullbyte am Ende).

> Die Unicode Map/das Encoding ascii (früher hat man
> dafür "charset" gesagt)? Oder ein Unicode-Zeichen, das im
> Codepoint-Bereich 0..127 vorkommt?

Ja, ich denke mal, dass das damit gemeint ist.

> Beachte, dass man solche
> Unicode-Zeichen durchaus mit zwei oder mehr Bytes speichern kann, wenn
> man als Encoding beispielsweise UCS-4 oder UTF-16 wählt.

Klar. Aber das tut Perl ja (noch) nicht.

LG, Ferry

--
Ing. Ferry Bolhar
Municipality of Vienna, Department 14
A-1010 Vienna / AUSTRIA
E-mail: bol@adv.magwien.gv.at

Re: [Regex] Suchen nach Hex-Zeichen

am 04.07.2006 23:59:18 von Slaven Rezic

"Ferry Bolhar" writes:

> Slaven Rezic:
>
> >> Der theoretische "Wertbereich" eines Pflurls liegt bei 32 Bit.
> >> Praktisch werden zumindest ASCII-Zeichen immer noch in
> >> 8 Bit abgespeichert.
> >
> > Vorsicht, jetzt wird es wieder ungenau. Was meinst du genau mit
> > "ASCII-Zeichen"?
>
> Damit meine ich zB., dass damit ein 'A' in einem Byte, und zwar
> als hex 41, abgespeichert wird. Oder der String "hello" als hex
> 68-65-6C-6C-6F-00, in 6 Bytes (mit dem Nullbyte am Ende).

Das Nullbyte ist Convenience für XS/C-Programmierung. Perl-Strings
kommen ausdrücklich ohne Nullbyte aus.

>
> > Die Unicode Map/das Encoding ascii (früher hat man
> > dafür "charset" gesagt)? Oder ein Unicode-Zeichen, das im
> > Codepoint-Bereich 0..127 vorkommt?
>
> Ja, ich denke mal, dass das damit gemeint ist.
>
> > Beachte, dass man solche
> > Unicode-Zeichen durchaus mit zwei oder mehr Bytes speichern kann, wenn
> > man als Encoding beispielsweise UCS-4 oder UTF-16 wählt.
>
> Klar. Aber das tut Perl ja (noch) nicht.
>

Dass Perl intern UTF-8 oder ISO-8859-1 verwendet, sollte dich nicht
interessieren. Aber du kannst

binmode(STDOUT, ":encoding(UCS-4)");

schreiben und damit sehr einfach auf ein anderes
Eingabe/Ausgabe-Encoding umschalten. Nur *das* sollte dich
interessieren. Theoretisch. Praktisch hilft es bei der Beschäftigung
mit Perl&Unicode ungemein, wenn man mit Devel::Peek in die Interna
schaut. Aber man sollte es wirklich nur als Debugging-Hilfe benutzen.

Gruß,
Slaven

--
Slaven Rezic - slaven rezic de

Tk-AppMaster: a perl/Tk module launcher designed for handhelds
http://tk-appmaster.sf.net

Re: [Regex] Suchen nach Hex-Zeichen

am 05.07.2006 09:14:33 von Ferry Bolhar

Slaven Rezic:

> Das Nullbyte ist Convenience für XS/C-Programmierung. Perl-Strings
> kommen ausdrücklich ohne Nullbyte aus.

Nicht alle. Stashnamen (Packagenamen) haben kein Längenfeld
(es gibt zB. nur ein HvSTASH bzw. SvSTASH Feld im HV/SV).
Die Länge des Namens ist implizit durch das den Namen
abschließende Nullbyte vorgegeben (wird ein String mit
Nullbytes als Stashnamen verwendet, so wird aus diesem
Grund nur der Teil bis zum ersten Nullbyte berücksichtigt).

> Dass Perl intern UTF-8 oder ISO-8859-1 verwendet, sollte dich nicht
> interessieren. Aber du kannst
>
> binmode(STDOUT, ":encoding(UCS-4)");
>
> schreiben und damit sehr einfach auf ein anderes
> Eingabe/Ausgabe-Encoding umschalten. Nur *das* sollte dich
> interessieren. Theoretisch. Praktisch hilft es bei der Beschäftigung
> mit Perl&Unicode ungemein, wenn man mit Devel::Peek in die Interna
> schaut. Aber man sollte es wirklich nur als Debugging-Hilfe benutzen.

ACK.

PS: Ich habe in diesem Thread einiges über Codierunsarten gelernt
und möchte mich bei allen Mitschreibern, vor allem bei Slaven Rezic,
Frank Seitz und Peter J. Holzer für die informativen Beiträge (und
ihre Geduld! :-) bedanken!

LG, Ferry

--
Ing. Ferry Bolhar
Municipality of Vienna, Department 14
A-1010 Vienna / AUSTRIA
E-mail: bol@adv.magwien.gv.at