| 1 |
root |
1.1 |
!init OPT_STYLE="paper" |
| 2 |
|
|
|
| 3 |
|
|
!define DOC_NAME "Perl und Unicode - eine gefährliche Mischung" |
| 4 |
|
|
!define DOC_AUTHOR "Marc Lehmann <pcg@goof.com>" |
| 5 |
|
|
!build_title |
| 6 |
|
|
|
| 7 |
|
|
H1: Encoding, Charsets, Glyphs |
| 8 |
|
|
|
| 9 |
|
|
Unicode, UTF-8 u.ä. wird oft in einen Topf geworfen. Das ist meist |
| 10 |
|
|
einfach und auch in Ordnung, wenn man die feinen Unterscheide kennt. Weil |
| 11 |
|
|
ich hier etwas genauer sein will, möchte ich zuerst einige Begriffe |
| 12 |
|
|
klären: |
| 13 |
|
|
|
| 14 |
|
|
* Charset (Zeichensatz). Ein Zeichensatz ist eine Menge von Zeichen |
| 15 |
|
|
in einer bestimmten Reihenfolge. Dadurch bekommt jedes Zeichen eine |
| 16 |
|
|
eindeutige Nummer. Unicode ist z.B. ein Zeichensatz. Das 9729te davon |
| 17 |
|
|
ist z.B. das Zeichen "CLOUD" (Wolke). |
| 18 |
|
|
|
| 19 |
|
|
* Encoding (Kodierung). Irgendwie werden diese Zeichennummern |
| 20 |
|
|
gespeichert. Bei vielen Zeichensätzen (z.B. ASCII = 128 Zeichen oder |
| 21 |
|
|
ISO-8859-1 = 256 Zeichen) reicht ein Byte (bzw. octet) aus. Hat man |
| 22 |
|
|
keine ungewöhnliche Rechnerarchitektur erscheint das natürlich. Bei |
| 23 |
|
|
Unicode (z.Zt. 524288 Zeichen!) geht das nicht mehr, eine "natürliche" |
| 24 |
|
|
Form der Speicherung gibt es nicht, deshalb gibt es mehrere Methoden, |
| 25 |
|
|
Zeichennummern auf Bytes abzubilden. Eine solche Methode ist ein |
| 26 |
|
|
"Encoding". UTF-8/UTF-16 oder UCS-4 sind Encodings. (UCS-2 hört man |
| 27 |
|
|
ebenfalls häufig, kann aber nur die ersten 2**16 Unicode-Zeichen |
| 28 |
|
|
darstellen und sollte nicht mehr verwendet werden). |
| 29 |
|
|
|
| 30 |
|
|
* Glyph. Das Unicode-Zeichen Nummer 9729 stellt eine Wolke dar. Wolken können |
| 31 |
|
|
je nach Font (Schrift) unterschiedlich aussehen. Ein Glyph ist nur eine Form |
| 32 |
|
|
oder eine Grafik, die den einzelnen Nummern zugeordnet werden. Mit Glyphen hat |
| 33 |
|
|
Perl nicht allzuviel zu tun. |
| 34 |
|
|
|
| 35 |
|
|
H2: Unicode |
| 36 |
|
|
|
| 37 |
|
|
Unicode wurde ursprünglich ins Leben gerufen, um mit der Vielfalt der |
| 38 |
|
|
Zeichensätze aufzuräumen, um {{einen}} Standard-Zeichensatz für |
| 39 |
|
|
praktisch alle Fälle zu erhalten. Mit Unicode ist es erstmals möglich, |
| 40 |
|
|
auch komplexe Texte (in mehreren Sprachen) in {{einem}} Zeichensatz zu |
| 41 |
|
|
verfassen, z.B. um ein Originalzitat von Gogol (in kyrillisch) in einem |
| 42 |
|
|
französischen Artikel unterzubringen. Dass man letzteres braucht hat mir |
| 43 |
|
|
erst Christian Kirsch erklären müssen, denn ich dachte immer, Gogols |
| 44 |
|
|
wären große Zahlen und keine Originalzitate... Unicode verbessert also |
| 45 |
|
|
auch die Allgemeinbildung ;) |
| 46 |
|
|
|
| 47 |
|
|
Die Normungsgruppe für den ISO-Standard 10646 (den Nachfolger |
| 48 |
|
|
von ISO-646, auch ASCII genannt ;) versuchte ebenfalls, einen |
| 49 |
|
|
Universalzeichensatz zu erstellen. Unicode hatte ursprünglich 16 Bit, |
| 50 |
|
|
ISO-10646 ursprünglich 31. |
| 51 |
|
|
|
| 52 |
|
|
Anfänglich gab es große Ablehnung gegen beide Vorhaben, meist, weil |
| 53 |
|
|
gleich aussehende Glyphen zu einem Zeichen zusammengefasst wurden - |
| 54 |
|
|
ein Unding. Aber ernsthaft: es gab viele kleine Fehler, die inzwischen |
| 55 |
|
|
größtenteils beseitigt wurden, so dass Unicode nicht mehr auf starke |
| 56 |
|
|
Ablehnung stößt. |
| 57 |
|
|
|
| 58 |
|
|
Da ISO-10646 niemals wirkliche Ergebnisse vorweisen konnte, wurde |
| 59 |
|
|
ISO-10646 mehr oder weniger als Unicode definiert und der Rest (ein |
| 60 |
|
|
ISO-10646-Zeichen umfaßt 31 Bit, ein paar mehr als Unicode!) der Zeichen |
| 61 |
|
|
blieb unbelegt. Unicode wurde mittlerweile auf 18 Bit erweitert (das war |
| 62 |
|
|
von Anfang an so vorgesehen, jedoch wurden die Zeichen anfänglich nicht |
| 63 |
|
|
belegt). |
| 64 |
|
|
|
| 65 |
|
|
H2: UTF-8 |
| 66 |
|
|
|
| 67 |
|
|
Eine spezielle Kodierung von Unicode ist UTF-8. Meiner ganz persönlichen und |
| 68 |
|
|
deshalb objektiven Meinung nach hat UTF-8 einige absolut geniale |
| 69 |
|
|
Eigenschaften{{}}: |
| 70 |
|
|
|
| 71 |
|
|
* es gibt keine eingebetteten Nullen. Die meisten Funktionen, die auf |
| 72 |
|
|
nullterminierte 8-Bit-Strings angewendet werden, können auch sinnvoll auf |
| 73 |
|
|
UTF-8 angewendet werden. |
| 74 |
|
|
|
| 75 |
|
|
* ASCII-Zeichen bleiben ASCII. Man kann immer noch nach "+" oder "$" |
| 76 |
|
|
suchen (einfache Parser). Wenn ein Byte im String den Wert 97 hat, ist |
| 77 |
|
|
es ein kleines "a". |
| 78 |
|
|
|
| 79 |
|
|
* UTF-8 ist platzsparend: ASCII belegt ein, die meisten ISO-Zeichensätze |
| 80 |
|
|
zwei Byte pro Zeichen und mit drei Byte kann man fast alle belegten |
| 81 |
|
|
Unicode-Zeichen erreichen (inklusive der meisten asiatischen |
| 82 |
|
|
Zeichen). Mit vier Byte lassen sich alle Unicode-Zeichen erreichen. |
| 83 |
|
|
|
| 84 |
|
|
* UTF-8 ist sicher: man kann jederzeit festellen, ob man sich am Anfang |
| 85 |
|
|
eines Multibyte-Zeichens oder in der Mitte befindet. So kann man auch |
| 86 |
|
|
mitten in einem String aufsetzen und resynchronisieren. Außerdem ist |
| 87 |
|
|
die Verwechslung von UTF-8 mit anderen Kodierungen unwahrscheinlich: |
| 88 |
|
|
ist ein Byte-Stream formal UTF-8, ist es mit hoher Wahrscheinlichkeit |
| 89 |
|
|
tatsächlich UTF-8 und nicht etwas anderes, wie ein JPEG-Bild oder |
| 90 |
|
|
Latin1 mit Umlauten. |
| 91 |
|
|
|
| 92 |
|
|
* Die Sortierreihenfolge wird auch bei strcmp (nicht-UTF-8-"cmp"-operator) |
| 93 |
|
|
eingehalten. Das hat in der Praxis allerdings geringe Bedeutung. |
| 94 |
|
|
|
| 95 |
|
|
UTF-8 nimmt also immer gleichviel oder weniger Platz ein als UCS-4 (4 |
| 96 |
|
|
Byte/Zeichen). UTF-16 ist manchmal kürzer, dafür handelt man sich |
| 97 |
|
|
aber mehr Nachteile ein (Multiword statt Multibyte, embeddete Nullen, |
| 98 |
|
|
Byteorder!). Speicherersparnis bringt auf neueren Architekturen meistens |
| 99 |
|
|
auch Zeitersparnis, so dass in den meisten Fällen UTF-8 sowohl UTF-16 |
| 100 |
|
|
als auch UCS-4 vorzuziehen ist, auch wenn die Algorithmen teilweise |
| 101 |
|
|
komplizierter werden. |
| 102 |
|
|
|
| 103 |
|
|
H1: Perl |
| 104 |
|
|
|
| 105 |
|
|
Perl - eine tolle Sprache, und sie kann auch Multibyte-Zeichen. Aber das |
| 106 |
|
|
leider nur sehr, sehr umständlich. Eine natürliche Implementation, bei |
| 107 |
|
|
dem einem der Perl-Interpreter die Arbeit abnimmt, wäre da toll. So |
| 108 |
|
|
dachte sich wohl Larry und baute UTF-8-Unterstützung in Perl ein. |
| 109 |
|
|
|
| 110 |
|
|
Das sah so aus, dass man in allen Programmteilen, die unter dem Einfluss eines |
| 111 |
|
|
{{C:use utf8}} standen, UTF-8-Semantik hatte, woanders jedoch nicht. Das hätte |
| 112 |
|
|
erfordert, dass man alle Module, die UTF-8-fähig werden sollten, umschreiben |
| 113 |
|
|
müsste. |
| 114 |
|
|
|
| 115 |
|
|
Um dem zu entgehen, wurde das Unicode-Modell von Perl geändert: Ein |
| 116 |
|
|
jeder Skalar weiß nun darüber Bescheid, ob er in ISO-Latin-1 ("Bytes") |
| 117 |
|
|
oder UTF-8 ("Unicode") kodiert ist. Die Operatoren ({{C:substr}}, |
| 118 |
|
|
{{C:s///}}...) kümmern sich um den Rest. |
| 119 |
|
|
|
| 120 |
|
|
Dann kam 5.6.0, mit UTF-8 support ("unicode-support"), ich portierte |
| 121 |
|
|
ein riesiges Modul, und freute mich daran. Daran, dass gar nichts |
| 122 |
|
|
funktioniert. Naja, es tat eigentlich alles, bis man auf die Idee kam, |
| 123 |
|
|
Umlaute oder etwas ähnliches einzusetzen. |
| 124 |
|
|
|
| 125 |
|
|
Damals hätte ich noch umsteigen können, aber so lernt man nichts. Also |
| 126 |
|
|
blieb ich bei Unicode, schrieb böse E-mails, weniger Patches und basierte |
| 127 |
|
|
meine Module auf bleedperl, dem aktuellen Perl-snapshot. Blut habe ich |
| 128 |
|
|
gelassen. |
| 129 |
|
|
|
| 130 |
|
|
Dass Perl nur "bytes" und "UTF-8" unterstützt, ist offiziell nur |
| 131 |
|
|
Zufall. Die interne Repräsentation von Zeichen sollte "geheim" sein - |
| 132 |
|
|
ich meine, das ist gefährlicher Unsinn, aber möglicherweise werden sich |
| 133 |
|
|
zukünftige Versionen von Perl nicht mehr so sehr auf UTF-8 vs. Bytes |
| 134 |
|
|
beschränken. Das zieht aber jede Menge Arbeit nach sich ("oh, die vielen |
| 135 |
|
|
Bugreports die wir bekommen werden wenn wir das ändern"), so dass mir die |
| 136 |
|
|
Gefahr recht gering erscheint. Wenn also jemand fragt: ich habe niemals |
| 137 |
|
|
behauptet, Perl würde intern irgendetwas Bestimmtes unterstützen. |
| 138 |
|
|
|
| 139 |
|
|
H2: Perl-5.7 |
| 140 |
|
|
|
| 141 |
|
|
Wenn man den richtigen Snapshot hat, läuft Perl-5.7 hervorragend. Der |
| 142 |
|
|
Unicode-Support ist gut, von einigen kleineren Problemen abgesehen (wer |
| 143 |
|
|
braucht {{C:tr///}}?). Ich werde mich im Folgenden mit der Version |
| 144 |
|
|
5.7-DEVEL7952 (ein älterer Snapshot) beschäftigen. Ich hoffe, dass viele |
| 145 |
|
|
bzw. die meisten Bugfixes in 5.6.1 einfließen. |
| 146 |
|
|
|
| 147 |
|
|
H1: Die Grundlagen |
| 148 |
|
|
|
| 149 |
|
|
H2: {{C:use utf8}} vs. {{C:use bytes}} |
| 150 |
|
|
|
| 151 |
|
|
Seit der Unicode-Einführung gibt es zwei neue Pragmas, {{C:use utf8}} und |
| 152 |
|
|
{{C:use bytes}}. Diese schalten {{nicht}} zwischen UTF-8- und Byte-Modus |
| 153 |
|
|
hin und her, sie erfüllen zwei grundsätzlich unterschiedliche Zwecke. |
| 154 |
|
|
|
| 155 |
|
|
H3: {{C:use bytes}} |
| 156 |
|
|
|
| 157 |
|
|
Das {{C:bytes}}-Pragma entscheidet während der Laufzeit darüber, welche |
| 158 |
|
|
{{Semantik}} die Perl-Operatoren haben. Grundsätzlich gibt es zwei |
| 159 |
|
|
mögliche Interpretationen für einen Skalar: Entweder enthält er Zeichen |
| 160 |
|
|
({{C:no bytes}}) oder irgendwelchen Binärkram ({{C:use bytes}}). Normalerweise |
| 161 |
|
|
macht Perl intuitiv das richtige (behaupten wir einfach mal). {{C:use bytes}} |
| 162 |
|
|
ist notwendig, wenn man sicher gehen will, dass Perl definitiv alles als |
| 163 |
|
|
Bytestring behandelt. Wenn man z.B. schreibt: |
| 164 |
|
|
|
| 165 |
|
|
!block perl |
| 166 |
|
|
$s = chr(9729); |
| 167 |
|
|
!endblock |
| 168 |
|
|
|
| 169 |
|
|
Dann enthält $s drei Bytes, da sich das Zeichen "9729" nur mittels drei Bytes |
| 170 |
|
|
kodieren läßt. Konsequenterweise liefert {{C:length $s}} auch den Wert "1" - ein |
| 171 |
|
|
Zeichen. Manchmal will man aber unbedingt, dass da Bytes drin stehen. Muss so |
| 172 |
|
|
sein. Dann schreibt man z.B. |
| 173 |
|
|
|
| 174 |
|
|
!block perl |
| 175 |
|
|
$length = do { use bytes; length $s }; |
| 176 |
|
|
!endblock |
| 177 |
|
|
|
| 178 |
|
|
Das liefert in unserem Beispiel 3. |
| 179 |
|
|
|
| 180 |
|
|
Das Ganze ist allerdings weit weniger sinnvoll, als es zuerst |
| 181 |
|
|
erscheint: Wenn {{C:$s}} z.B. ein JPEG-Bild enthält, dann ist es völlig |
| 182 |
|
|
wurscht, ob es durch irgendeinen internen Schluckauf innerhalb von Perl |
| 183 |
|
|
mal in UTF-8 umgewandelt wird - die Länge in Zeichen bleibt immer |
| 184 |
|
|
gleich. Nur bei der Ausgabe bekommt man Probleme, aber auch da hilft einen die |
| 185 |
|
|
Länge in Bytes nichts - wenn Perl meint, es wären Bytes in unserem Skalar, |
| 186 |
|
|
stimmt das normale length. Wenn Perl meint, es wäre UTF-8 drin, stimmt es auch. |
| 187 |
|
|
|
| 188 |
|
|
Deshalb ist es fraglich, was genau ein {{C:use bytes}} eigentlich bedeutet - so |
| 189 |
|
|
ganz klar scheint es auch den perl5-porters nicht zu sein - man braucht es |
| 190 |
|
|
relativ selten. Meistens muss man es nur abschalten, um ganz sicher zu gehen, |
| 191 |
|
|
dass der aktuelle Snapshot auch spurt. |
| 192 |
|
|
|
| 193 |
|
|
Übrigens konvertiert Perl recht selten einen Skalar in UTF-8, solange man |
| 194 |
|
|
nicht irgendwo im Programm explizit mit sowas anfängt. Programme, die |
| 195 |
|
|
kein UTF-8 benutzen, sind also sicher. |
| 196 |
|
|
|
| 197 |
|
|
H3: {{C:use utf8}} |
| 198 |
|
|
|
| 199 |
|
|
Wozu könnte nun das {{C:use utf8}} gut sein? Nun ja, wer die Diskussion |
| 200 |
|
|
um die Einführung eines neuen Operators mitbekommen hat (z.B. den |
| 201 |
|
|
{{C:??}}-Operator, genannt "Huh?", der übrigens sehr sinnvoll ist...) |
| 202 |
|
|
weiß, dass solche Sachen nicht leichtgenommen werden. Hey, wenn der |
| 203 |
|
|
Quellcode in UTF-8 ist... könnte man ja Unicode-Zeichen als Operatoren |
| 204 |
|
|
nehmen - davon gibt's ja genug! |
| 205 |
|
|
|
| 206 |
|
|
Das ist aber nicht das Hauptargument dafür, schon den Quellcode in UTF-8 zu |
| 207 |
|
|
schreiben. Auch String-Konstanten könnten ja schön leserlich in UTF-8 sein. Oder |
| 208 |
|
|
in ganz anderen Zeichensätzen oder Encodings. |
| 209 |
|
|
|
| 210 |
|
|
Ein bisschen davon bringt uns ein {{C:use utf8}}. In dessen |
| 211 |
|
|
Gültigkeitsbereich erwartet Perl, dass der Quellcode selbst in UTF-8 |
| 212 |
|
|
verfasst wird. Ausserhalb davon (bzw. nach einem {{C:no utf8}}) erwartet |
| 213 |
|
|
Perl z.Zt. ISO-8859-1, bzw. gar nichts Bestimmtes, es ist einfach nur |
| 214 |
|
|
undefiniert). {{C:use utf8}} wird möglicherweise der Default in |
| 215 |
|
|
zukünftigen Perl-Versionen. |
| 216 |
|
|
|
| 217 |
|
|
Ein kompliziertes Beispiel will ich auf Rücksicht auf unseren wackeren |
| 218 |
|
|
"Setzer" nicht bringen, der hat mit meinen Vorlagen bestimmt schon genug |
| 219 |
|
|
zu kämpfen, aber dennoch: |
| 220 |
|
|
|
| 221 |
|
|
!block perl |
| 222 |
|
|
use utf8; |
| 223 |
|
|
$s = "Er erwürgt mich!"; # <- da steht ein "ü" in UTF-8! |
| 224 |
|
|
print length($s),"\n$s\n"; |
| 225 |
|
|
!endblock |
| 226 |
|
|
|
| 227 |
|
|
Dieses Programmfragment gibt zuerst die Zahl 16 und danach in einer |
| 228 |
|
|
separaten Zeile 17 Bytes aus - das "ü" benötigt zwei Bytes. Streicht man |
| 229 |
|
|
das {{C:use utf8}} weg, bekommt man die Zahl 17 und danach 17 |
| 230 |
|
|
Bytes - das "ü" sind für Perl nun nur noch zwei beliebige 8-Bit-Zeichen, |
| 231 |
|
|
die zwar keinen Sinn ergeben, aber sowas ist Perl ziemlich egal. |
| 232 |
|
|
|
| 233 |
|
|
Wenn wir übrigens schonmal dabei sind: |
| 234 |
|
|
|
| 235 |
|
|
!block perl |
| 236 |
|
|
use utf8; |
| 237 |
|
|
|
| 238 |
|
|
$lücke = "voll"; |
| 239 |
|
|
!endblock |
| 240 |
|
|
|
| 241 |
|
|
Eine Variable (Funktion... Filehandle...) mit Umlauten oder noch |
| 242 |
|
|
schlimmeren Zeichen ist an sich nichts Besonderes (das ging über |
| 243 |
|
|
symbolische Referenz schon immer), aber mit C<use utf8> kann man jetzt |
| 244 |
|
|
endlich auch direkt im Quelltext UTF-8-Zeichen verwenden, vorausgesetzt, |
| 245 |
|
|
sie sind "Wort"-Zeichen im Sinne von Unicode. Ich sehe eine grosse Zukunft für |
| 246 |
|
|
den Obfuscated Perl Contest... |
| 247 |
|
|
|
| 248 |
|
|
H3: String-Konstanten und -Funktionen |
| 249 |
|
|
|
| 250 |
|
|
Mit einem {{C:use utf8}} bekommt man also Unicode in seine Skalare, aber |
| 251 |
|
|
nicht jeder hat einen Editor, der UTF-8 beherrscht, und selbst dann werden |
| 252 |
|
|
Dateien gerne mal konvertiert - wer hat wohl nicht einen Rechner zuhause, |
| 253 |
|
|
der unbedingt EBCDIC-DE benötigt.... |
| 254 |
|
|
|
| 255 |
|
|
Ein Weg, Unicode-Zeichen in sein Programm zu bringen, ist |
| 256 |
|
|
{{C:chr()}}. Wenn man bei {{C:chr()}} eine Zahl <128 übergibt, bekommt |
| 257 |
|
|
man ein ASCII-Zeichen. Bei >255 bekommt man UTF-8, und dazwischen - |
| 258 |
|
|
genau: Glückssache. Genaugenommen entscheidet dann ein etwaiges {{C:use |
| 259 |
|
|
utf8}}, ob man ein Byte oder ein UTF-8-Zeichen bekommt. |
| 260 |
|
|
|
| 261 |
|
|
Die {{C:ord()}}-Funktion funktioniert übrigens immer korrekt - solange |
| 262 |
|
|
Perl weiss, was in dem Skalar gespeichert ist. Notfalls muss man selbst |
| 263 |
|
|
dafür sorgen. |
| 264 |
|
|
|
| 265 |
|
|
Wer ganz sicher gehen will, kann mittels Backslash-Escape Unicode in |
| 266 |
|
|
Strings einbetten: |
| 267 |
|
|
|
| 268 |
|
|
!block perl |
| 269 |
|
|
$s = "Er erw\x{FC}rgt mich!"; |
| 270 |
|
|
!endblock |
| 271 |
|
|
|
| 272 |
|
|
Das erzeugt einen UTF-8-String, Länge 16, 17 Bytes |
| 273 |
|
|
lang. Immer. Zumindest in DEVEL7952 ;) |
| 274 |
|
|
|
| 275 |
|
|
Unsere Wolke könnte man so ausgeben: |
| 276 |
|
|
|
| 277 |
|
|
!block perl |
| 278 |
|
|
print "\x{2601}"; # 0x2601 == 9729 |
| 279 |
|
|
!endblock |
| 280 |
|
|
|
| 281 |
|
|
Aber es geht noch besser, mit dem {{C:\N}}-Escape kann Zeichen auch per Namen |
| 282 |
|
|
ansprechen: |
| 283 |
|
|
|
| 284 |
|
|
!block perl |
| 285 |
|
|
use charnames ':full'; |
| 286 |
|
|
|
| 287 |
|
|
print "\N{CLOUD}"; |
| 288 |
|
|
print "\N{LATIN SMALL LETTER A}"; |
| 289 |
|
|
|
| 290 |
|
|
use charnames ':short'; |
| 291 |
|
|
print "\N{greek:sigma}"; |
| 292 |
|
|
!endblock |
| 293 |
|
|
|
| 294 |
|
|
Die muss man aber erst mit dem {{C:charnames}}-Pragma "importieren". Es |
| 295 |
|
|
gibt jede Menge Möglichkeiten, Zeichen nach Namen zu finden, inklusive |
| 296 |
|
|
der selbsterdachten - {{C:perldoc charnames}} gibt Auskunft. |
| 297 |
|
|
|
| 298 |
|
|
H2: Holzhammer |
| 299 |
|
|
|
| 300 |
|
|
Bevor ich zu den regulären Ausdrücken komme ("jaaaa"), muss ich nochmal |
| 301 |
|
|
Abschweifen ("neiiin"!). Perl macht nicht das, was es soll. Ob nie, |
| 302 |
|
|
manchmal oder immer, hängt vom Programm ab. Wie behilft man sich, wenn |
| 303 |
|
|
man doch so gerne UTF-8 nutzen würde, es aber irgendwie hakt? Häufiges |
| 304 |
|
|
Beispiel{{}}: "Mein String enthält Daten im Binärformat, aber irgendein |
| 305 |
|
|
Schwein hat es in UTF-8 umgewandelt. Wie gebe ich das denn jetzt aus?". |
| 306 |
|
|
|
| 307 |
|
|
Da gibt es mehrere Möglichkeiten, aber externe Hilfe (sprich: ein |
| 308 |
|
|
Modul) braucht man. Bei Perl-5.7 ist eines dabei, es nennt sich |
| 309 |
|
|
{{C:Encode}}. Leider habe ich schlechte Erfahrungen damit gemacht, und da |
| 310 |
|
|
sich die API sehr wahrscheinlich ändern wird, nehme ich im Folgenden das |
| 311 |
|
|
ältere {{C:Convert::Scalar}}, dafür muss man leider den Umweg über CPAN |
| 312 |
|
|
machen, das macht sich aber durch eine größere Nähe zu den Bits & Bytes |
| 313 |
|
|
bezahlt. |
| 314 |
|
|
|
| 315 |
|
|
Betrachten wir mal dies: |
| 316 |
|
|
|
| 317 |
|
|
!block perl |
| 318 |
|
|
use Convert::Scalar ':utf8'; |
| 319 |
|
|
|
| 320 |
|
|
$x = big_complicated_function_that_might_return_utf8(...); |
| 321 |
|
|
utf8_downgrade $x; |
| 322 |
|
|
print $x; |
| 323 |
|
|
!endblock |
| 324 |
|
|
|
| 325 |
|
|
Egal, was in {{C:$x}} drinsteht - solange es sich in Bytes darstellen |
| 326 |
|
|
lässt, bekommen wir Bytes. Die Funktionen in {{C:Convert::Scalar}} |
| 327 |
|
|
verändern dabei das Argument direkt und geben es meistens zurück (jaja, |
| 328 |
|
|
{{C:utf8_downgrade}} ist die Ausnahme, es gibt einen Wahrheitswert |
| 329 |
|
|
zurück, der angibt, ob's geklappt hat), d.h. hinterher steht in {{C:$x}} |
| 330 |
|
|
ein Bytestring. |
| 331 |
|
|
|
| 332 |
|
|
Was passiert, wenn Zeichen >255 in {{C:$x}} stehen? Dann steigt |
| 333 |
|
|
{{utf8_downgrade}} mit einem Laufzeitfehler aus (Den kann man mit |
| 334 |
|
|
{{C:utf8_downgrade $skalar, 1}} umgehen um z.B. den Rückgabewert |
| 335 |
|
|
auszuwerten). |
| 336 |
|
|
|
| 337 |
|
|
Andersherum geht es auch: Wir haben einen Skalar (unbekannter Herkunft, |
| 338 |
|
|
d.h. unbekannter Kodierung) und möchten UTF-8 ausgeben (oder benötigen |
| 339 |
|
|
aus anderen Gründen UTF-8). Dafür gibt es {{C:utf8_upgrade}}: |
| 340 |
|
|
|
| 341 |
|
|
!block perl |
| 342 |
|
|
$x = ganz_komische_funktion(); |
| 343 |
|
|
print utf8_upgrade $x; |
| 344 |
|
|
!endblock |
| 345 |
|
|
|
| 346 |
|
|
Im Gegensatz zu {{C:utf8_downgrade}} kann das niemals schiefgehen, weshalb |
| 347 |
|
|
die Funktion günstigerweise eine Kopie des Skalars zurückliefert. |
| 348 |
|
|
|
| 349 |
|
|
Also{{}}: {{C:utf8_downgrade}} und {{C:utf8_upgrade}} benötigt man dann, wenn |
| 350 |
|
|
man sichergehen will, dass Perl einen Skalar in einer bestimmten Kodierung |
| 351 |
|
|
speichert. Eigentlich benötigt man sie dann, wenn der Sch**** (siehe |
| 352 |
|
|
auch: "Reguläre Ausdrücke" \N{SMILEY}) wieder nicht geht und man einfach |
| 353 |
|
|
{{will}}, dass das Programm endlich funktioniert. |
| 354 |
|
|
|
| 355 |
|
|
Das Herumwandeln der Kodierung (das tun Kodierungen besonders gerne |
| 356 |
|
|
nachts) ist meistens unproblematisch: Perl weiß immer, welche Kodierung |
| 357 |
|
|
verwendet wird und kann nötigenfalls automatisch umwandeln. Manchmal |
| 358 |
|
|
meint Perl aber, der Skalar wäre in einer bestimmten Kodierung, obwohl |
| 359 |
|
|
dies gar nicht der Fall ist (z.B. wenn wir einen Textstring aus einer |
| 360 |
|
|
UTF-8-Datei gelesen haben). Perl setzt die Kodierung entsprechend der |
| 361 |
|
|
Umgebung ({{utf8}}-Pragma, Mondphase, Laune...). Ein Beispiel: Holen wir |
| 362 |
|
|
einmal die aktuelle Mondphase aus einer SQL-Datenbank: |
| 363 |
|
|
|
| 364 |
|
|
!block perl |
| 365 |
|
|
use PApp::SQL; |
| 366 |
|
|
$phase = sql_fetch "select phase from mondphasen where tag = ?", $tag; |
| 367 |
|
|
!endblock |
| 368 |
|
|
|
| 369 |
|
|
Nun ist C<$phase> in UTF-8. Oder doch nicht? Jaja, es ist schon in UTF-8, aber |
| 370 |
|
|
Perl weiss das vielleicht noch nicht? Dafür gibt es {{C:utf8_on}}: |
| 371 |
|
|
|
| 372 |
|
|
!block perl |
| 373 |
|
|
$phase = utf8_on sql_fetch "select... |
| 374 |
|
|
!endblock |
| 375 |
|
|
|
| 376 |
|
|
Jetzt gibt es keine Fragen mehr: C<utf8_on> setzt einfach das UTF-8-Flag, egal, |
| 377 |
|
|
ob es vorher gesetzt war oder nicht. Natürlich gibt es entsprechend auch ein |
| 378 |
|
|
C<utf8_off>, es wird aber seltener eingesetzt. Warum? Nehmen wir mal an, wir |
| 379 |
|
|
würden die Phase in der Datenbank ändern: |
| 380 |
|
|
|
| 381 |
|
|
!block perl |
| 382 |
|
|
sql_exec "update mondphasen set phase = ? where tag = ?", utf8_upgrade $phase, $tag; |
| 383 |
|
|
!endblock |
| 384 |
|
|
|
| 385 |
|
|
Warum um Himmels willen nicht C<utf8_off> oder C<utf8_downgrade>? Nun, |
| 386 |
|
|
nehmen wir einmal an, unsere Datenbank (+Perl-Interface!) verstünde UTF-8 |
| 387 |
|
|
(gibt es sowas?). Dann ist alles in Ordnung: wir lügen nicht, geben immer UTF-8 |
| 388 |
|
|
an die Datenbank, und unser C<utf8_on> ist ein NOP. |
| 389 |
|
|
|
| 390 |
|
|
Wenn unsere Datenbank (oder das DBI-Interface) kein UTF-8 versteht, |
| 391 |
|
|
übergeben wir die Daten immer in UTF-8-Kodierung ("Dübel" kann in Perl |
| 392 |
|
|
5 oder 6 Byte lang sein!), sie werden also {{normiert}}. Innerhalb der |
| 393 |
|
|
Datenbank geht meistens auch alles gut (sie hält unsere Strings dann eben |
| 394 |
|
|
für was anderes, aber dank der gutmütigen Eigenschaften von UTF-8 macht |
| 395 |
|
|
das selten Probleme). Und beim Angeln der Daten wird das UTF-8-Flag wieder |
| 396 |
|
|
gesetzt. |
| 397 |
|
|
|
| 398 |
|
|
Falls die Datenbank irgendwann mal UTF-8 beherscht, muss man alle Spalten |
| 399 |
|
|
nur mit dem Äquivalent von C<utf8_on> behandeln und alles läuft weiter. |
| 400 |
|
|
|
| 401 |
|
|
Anderes Beispiel: C<XML::Parser>. Dieses Modul gibt, wie wir ja alle |
| 402 |
|
|
wissen, UTF-8 zurück. Auch in Perl5.005. Halt ohne UTF-8-Flag. Das |
| 403 |
|
|
bedeutet, dass je nachdem, in welcher Version XML::Parser vorhanden ist |
| 404 |
|
|
und unter welcher Perl-Version es übersetzt wurde (jaa!) manchmal das |
| 405 |
|
|
UTF-8-Flag gesetzt ist und manchmal nicht. Deshalb: C<utf8_on> verwenden, |
| 406 |
|
|
wir wissen ja, es steckt UTF-8 drin. |
| 407 |
|
|
|
| 408 |
|
|
H3: Line Disciplines |
| 409 |
|
|
|
| 410 |
|
|
Eine ganz tolle Sache wird passieren: C<utf8_on> usw. wird vollständig |
| 411 |
|
|
verschwinden. Das ist nicht toll? Ja, dafür bekommen wir die |
| 412 |
|
|
Line-Disciplines. Damit kann man z.B. sagen "STDIN ist ab jetzt in UTF-8" |
| 413 |
|
|
oder besser: "STDIN ist ab jetzt in ISO-2022-JP". Die Klassengesellschaft |
| 414 |
|
|
wird abgeschafft, alle Kodierungen sind gleich(er). Und meinen Quellcode |
| 415 |
|
|
möchte ich bitteschön auch in ISO-2022-JP (JP für Japan ;) kodieren |
| 416 |
|
|
können! |
| 417 |
|
|
|
| 418 |
|
|
Noch weiß niemand, wie das aussehen soll, und ich glaube, es wird |
| 419 |
|
|
noch ein bisschen dauern. Inzwischen wird das C<Encode>-Modul einige |
| 420 |
|
|
Funktionen anbieten, mit denen man den Datentyp "Zeichen in Bytes" in |
| 421 |
|
|
UTF-8 umkodieren kann, also eine Art C<utf8_upgrade>/C<downgrade> für |
| 422 |
|
|
beliebige Zeichensätze. |
| 423 |
|
|
|
| 424 |
|
|
Aber ganz so weit sind wir noch nicht. |
| 425 |
|
|
|
| 426 |
|
|
H2: Reguläre Ausdrücke |
| 427 |
|
|
|
| 428 |
|
|
Wer Textverarbeitung betreibt, benötigt reguläre Ausdrucke, am besten die |
| 429 |
|
|
nicht-reguläre Variante in Perl ;) Wie andere Sprachen auskommen, wird mir für |
| 430 |
|
|
immer ein Rätsel..., ehrm... wo war ich stehengeblieben? |
| 431 |
|
|
|
| 432 |
|
|
Reguläre Ausdrücke beherrschen UTF-8. Meistens jedenfalls. Je nachdem, |
| 433 |
|
|
ob sie unter C<use utf8> oder C<no utf8> kompiliert(!) wurden (siehe auch: |
| 434 |
|
|
"Mondphase"), beherrschen sie genau diese Variante. Das ist nicht schlimm, |
| 435 |
|
|
leider kodiert Perl die Strings vorher nicht um... |
| 436 |
|
|
|
| 437 |
|
|
Folgendes{{}}: |
| 438 |
|
|
|
| 439 |
|
|
!block perl |
| 440 |
|
|
sub escape_attr { |
| 441 |
|
|
local $_ = shift; |
| 442 |
|
|
s/(['<>&\x00-\x1f\x80-\x9f])/sprintf "&#%d;", ord($1)/ge; |
| 443 |
|
|
$_; |
| 444 |
|
|
} |
| 445 |
|
|
!endblock |
| 446 |
|
|
|
| 447 |
|
|
ist absolut {{tödlich}}!! Das klappt nur mit... tja, eben solchen Strings, die |
| 448 |
|
|
die gleiche Kodierung haben, mit der die Regex kompiliert wurde. Da hilft nur |
| 449 |
|
|
der Holzhammer: |
| 450 |
|
|
|
| 451 |
|
|
!block perl |
| 452 |
|
|
sub escape_attr { |
| 453 |
|
|
local $_ = shift; |
| 454 |
|
|
use utf8; |
| 455 |
|
|
utf8_upgrade $_; # jetzt ist es UTF-8 |
| 456 |
|
|
s/(['<>&\x00-\x1f\x80-\x9f])/sprintf "&#%d;", ord($1)/ge; |
| 457 |
|
|
utf8_on $_; # je nach Perl-Snapshot ist das hilfreich |
| 458 |
|
|
$_; |
| 459 |
|
|
} |
| 460 |
|
|
!endblock |
| 461 |
|
|
|
| 462 |
|
|
Im übrigen können da die lustigsten Effekte passieren. In manchen |
| 463 |
|
|
Versionen geht die zweite Zeile, die erste aber nicht: |
| 464 |
|
|
|
| 465 |
|
|
!block perl |
| 466 |
|
|
s/(.)/$1/g; # geht (manchmal) |
| 467 |
|
|
s/(.)/my $x = $1; $x/ge; # geht (meistens) |
| 468 |
|
|
!endblock |
| 469 |
|
|
|
| 470 |
|
|
Sie sehen den Unterschied nicht? Tja, Sie haben eben noch keine 4 Stunden |
| 471 |
|
|
lang daran herumdebugged. Aber das sind alte Geschichten, so etwas |
| 472 |
|
|
passiert dann {{doch}} seltener und ist dann ein Bug in Perl (in diesem |
| 473 |
|
|
Fall liegt es daran, dass C<$1> recht magisch ist und seinen Inhalt erst |
| 474 |
|
|
recht spät zugewiesen bekommt). Das Beispiel soll nur zeigen, dass man |
| 475 |
|
|
durchaus den Mut besitzen sollte, Perl eines Fehlers zu bezichtigen. Das |
| 476 |
|
|
kommt sonst nämlich sehr selten vor. |
| 477 |
|
|
|
| 478 |
|
|
H3: Erweiterungen innerhalb von regulären Ausdrücken |
| 479 |
|
|
|
| 480 |
|
|
Bis jetzt ging es eigentlich nur um die Grundlagen (bzw. wie man Fehler |
| 481 |
|
|
umgeht). Aber um Unicode parsen zu können, braucht man schon ein paar |
| 482 |
|
|
mehr Werkzeuge, als es frühere Perlen angeboten haben. |
| 483 |
|
|
|
| 484 |
|
|
Stürzen wir uns einmal auf Zeichenklassen. C<\W> kennt fast jeder. Ich |
| 485 |
|
|
benutze es dauernd, im festen Wissen, dass es eigentlich nicht ganz |
| 486 |
|
|
korrekt ist. Bei Unicode ist es sogar meistens ganz falsch, denn die |
| 487 |
|
|
Gruppe der "Wort-Zeichen" ist bei Unicode-Anwendungen größer. Oder |
| 488 |
|
|
einfach anders... Da die Zahl der einbuchstabigen Abkürzungen |
| 489 |
|
|
begrenzt ist (ein Problem, vor dem auch die POSIX-Zeichenklassen |
| 490 |
|
|
standen) hat man zwei neue Escapes eingeführt: C<\p{EIGENSCHAFT}> |
| 491 |
|
|
und C<\P{EIGENSCHAFT}>. Klein-p steht für ein einzelnes Zeichen |
| 492 |
|
|
in der benannten Eigenschaft, z.B. steht C<\p{IsWord}> für ein |
| 493 |
|
|
Wort-Zeichen (also in etwa das, was man sich normalerweise unter C<\W> |
| 494 |
|
|
vorstellt). Gross-P ist das Gegenteil (nicht-Eigenschaft). |
| 495 |
|
|
|
| 496 |
|
|
Die folgende Zeile sucht nach einem Bezeichner, der mit einem Buchstaben |
| 497 |
|
|
anfängt und danach aus alphanumerischen (inklusive "_") Zeichen |
| 498 |
|
|
besteht auf die {{kein}} "Freiraum" folgt. Es ist etwas an den Haaren |
| 499 |
|
|
herbeigezogen... |
| 500 |
|
|
|
| 501 |
|
|
!block perl |
| 502 |
|
|
$s =~ /\p{IsAlpha}[\p{IsAlnum}_]*(?=\P{IsSpace})/; |
| 503 |
|
|
!endblock |
| 504 |
|
|
|
| 505 |
|
|
Die Namen für die Zeichenklassen findet man übrigens nur im Camel, |
| 506 |
|
|
kann eigentlich nicht sein, aber ich habe nirgendwo etwas gefunden (vor |
| 507 |
|
|
allem nicht dort, wohin man in der Dokumentation verwiesen wird). Eine |
| 508 |
|
|
kleine Liste bekommt man mit C<perldoc perlretut> und C<perldoc perlre>, |
| 509 |
|
|
ansonsten muss man sich direkt das C<unicode>-Unterverzeichnis im |
| 510 |
|
|
Perl-Library-Verzeichnis ansehen. Oder den Unicode-Standard, wobei man |
| 511 |
|
|
aber raten muss, wie die entsprechende Klasse in Perl heißt. Oder was die |
| 512 |
|
|
Zeichenklasse macht. |
| 513 |
|
|
|
| 514 |
|
|
Ein weiteres, nützliches Escape-Zeichen ist C<\X>, das passt auf ein |
| 515 |
|
|
Unicode-Zeichen inklusive darauffolgender Akzente oder ähnlicher Zeichen |
| 516 |
|
|
(sogenannte "combining chars", C<n> + (combining) C<~> == C<ñ>). |
| 517 |
|
|
|
| 518 |
|
|
H1: Ausblick |
| 519 |
|
|
|
| 520 |
|
|
Was wird sich noch tun? Nun, zum einen wird die Restriktion auf |
| 521 |
|
|
UTF-8/nicht-UTF-8 entschärft. Es gibt keinen Grund, {{ausschließlich}} |
| 522 |
|
|
UTF-8 zuzulassen. Wenn man schon jedes Unicode-Zeichen in Bezeichnern |
| 523 |
|
|
zulässt, dann sollte das auch in jeder Kodierung möglich sein. |
| 524 |
|
|
|
| 525 |
|
|
Ebenso sollte die interne Repräsentation nicht mehr so stark |
| 526 |
|
|
hervortreten, so dass man später nur noch zwischen "Bytes" und "Zeichen" |
| 527 |
|
|
unterscheidet. Wie das genau aussehen soll, ist mir nicht klar, es scheint |
| 528 |
|
|
mir sehr kompliziert. |
| 529 |
|
|
|
| 530 |
|
|
Das Wichtigste sind die sog. "line disciplines", von denen man sich |
| 531 |
|
|
sehr viel Arbeitserleichterung erhoffen kann; da die meisten Daten doch |
| 532 |
|
|
irgendwann über ein Filehandle gelesen (oder geschrieben) werden, |
| 533 |
|
|
kann man an dieser Stelle zweckmäßigerweise eine Konvertierung |
| 534 |
|
|
durchführen. Das funktioniert natürlich nicht bei "Dateien", auf |
| 535 |
|
|
denen Binär- und Textdaten gemischt werden (also fast alle, man |
| 536 |
|
|
denke z.B. an die Netzwerkverbindung zur Datenbank ;). Ja, liebe |
| 537 |
|
|
Unix-Freunde: C<binmode> wird auch Unix treffen, erschlagen und nie wieder |
| 538 |
|
|
weiterziehen. |
| 539 |
|
|
|
| 540 |
|
|
A1: Links |
| 541 |
|
|
|
| 542 |
|
|
* RFC 2279: UTF-8, a transformation format of ISO 10646 |
| 543 |
|
|
* {{C:perldoc charnames}} - Zeichennamen |
| 544 |
|
|
* {{C:perldoc perlunicode}} - was geht alles NICHT? |
| 545 |
|
|
* C<PERL5LIB/unicode/*> - Unicode Dateien |
| 546 |
|
|
* C<http://www.unicode.org/>, der Unicode-Standard |
| 547 |
|
|
|
| 548 |
|
|
|
| 549 |
|
|
|
| 550 |
|
|
|
| 551 |
|
|
|