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 gültiges UTF-8, ist es mit hoher |
89 |
Wahrscheinlichkeit tatsächlich UTF-8 und nicht etwas anderes, wie ein |
90 |
JPEG-Bild oder 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 einem 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 man Zeichen auch |
282 |
per Namen 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 |
429 |
besten die nicht-reguläre Variante in Perl ;) Wie andere Sprachen |
430 |
ohne auskommen, wird mir für immer ein Rätsel..., ehrm... wo war ich |
431 |
stehengeblieben? |
432 |
|
433 |
Reguläre Ausdrücke beherrschen UTF-8. Meistens jedenfalls. Je nachdem, |
434 |
ob sie unter C<use utf8> oder C<no utf8> kompiliert(!) wurden (siehe auch: |
435 |
"Mondphase"), beherrschen sie genau diese Variante. Das ist nicht schlimm, |
436 |
leider kodiert Perl die Strings vorher nicht um... |
437 |
|
438 |
Folgendes{{}}: |
439 |
|
440 |
!block perl |
441 |
sub escape_attr { |
442 |
local $_ = shift; |
443 |
s/(['<>&\x00-\x1f\x80-\x9f])/sprintf "&#%d;", ord($1)/ge; |
444 |
$_; |
445 |
} |
446 |
!endblock |
447 |
|
448 |
ist absolut {{tödlich}}!! Das klappt nur mit... tja, eben solchen Strings, die |
449 |
die gleiche Kodierung haben, mit der die Regex kompiliert wurde. Da hilft nur |
450 |
der Holzhammer: |
451 |
|
452 |
!block perl |
453 |
sub escape_attr { |
454 |
local $_ = shift; |
455 |
use utf8; |
456 |
utf8_upgrade $_; # jetzt ist es UTF-8 |
457 |
s/(['<>&\x00-\x1f\x80-\x9f])/sprintf "&#%d;", ord($1)/ge; |
458 |
utf8_on $_; # je nach Perl-Snapshot ist das hilfreich |
459 |
$_; |
460 |
} |
461 |
!endblock |
462 |
|
463 |
Im übrigen können da die lustigsten Effekte passieren. In manchen |
464 |
Versionen geht die zweite Zeile, die erste aber nicht: |
465 |
|
466 |
!block perl |
467 |
s/(.)/$1/g; # geht (manchmal) |
468 |
s/(.)/my $x = $1; $x/ge; # geht (meistens) |
469 |
!endblock |
470 |
|
471 |
Sie sehen den Unterschied nicht? Tja, Sie haben eben noch keine 4 Stunden |
472 |
lang daran herumdebugged. Aber das sind alte Geschichten, so etwas |
473 |
passiert dann {{doch}} seltener und ist dann ein Bug in Perl (in diesem |
474 |
Fall liegt es daran, dass C<$1> recht magisch ist und seinen Inhalt erst |
475 |
recht spät zugewiesen bekommt). Das Beispiel soll nur zeigen, dass man |
476 |
durchaus den Mut besitzen sollte, Perl eines Fehlers zu bezichtigen. Das |
477 |
kommt sonst nämlich sehr selten vor. |
478 |
|
479 |
H3: Erweiterungen innerhalb von regulären Ausdrücken |
480 |
|
481 |
Bis jetzt ging es eigentlich nur um die Grundlagen (bzw. wie man Fehler |
482 |
umgeht). Aber um Unicode parsen zu können, braucht man schon ein paar |
483 |
mehr Werkzeuge, als es frühere Perlen angeboten haben. |
484 |
|
485 |
Stürzen wir uns einmal auf Zeichenklassen. C<\W> kennt fast jeder. Ich |
486 |
benutze es dauernd, im festen Wissen, dass es eigentlich nicht ganz |
487 |
korrekt ist. Bei Unicode ist es sogar meistens ganz falsch, denn die |
488 |
Gruppe der "Wort-Zeichen" ist bei Unicode-Anwendungen größer. Oder |
489 |
einfach anders... Da die Zahl der einbuchstabigen Abkürzungen |
490 |
begrenzt ist (ein Problem, vor dem auch die POSIX-Zeichenklassen |
491 |
standen) hat man zwei neue Escapes eingeführt: C<\p{EIGENSCHAFT}> |
492 |
und C<\P{EIGENSCHAFT}>. Klein-p steht für ein einzelnes Zeichen |
493 |
in der benannten Eigenschaft, z.B. steht C<\p{IsWord}> für ein |
494 |
Wort-Zeichen (also in etwa das, was man sich normalerweise unter C<\W> |
495 |
vorstellt). Gross-P ist das Gegenteil (nicht-Eigenschaft). |
496 |
|
497 |
Die folgende Zeile sucht nach einem Bezeichner, der mit einem Buchstaben |
498 |
anfängt und danach aus alphanumerischen (inklusive "_") Zeichen |
499 |
besteht auf die {{kein}} "Freiraum" folgt. Es ist etwas an den Haaren |
500 |
herbeigezogen... |
501 |
|
502 |
!block perl |
503 |
$s =~ /\p{IsAlpha}[\p{IsAlnum}_]*(?=\P{IsSpace})/; |
504 |
!endblock |
505 |
|
506 |
Die Namen für die Zeichenklassen findet man übrigens nur im Camel, |
507 |
kann eigentlich nicht sein, aber ich habe nirgendwo etwas gefunden (vor |
508 |
allem nicht dort, wohin man in der Dokumentation verwiesen wird). Eine |
509 |
kleine Liste bekommt man mit C<perldoc perlretut> und C<perldoc perlre>, |
510 |
ansonsten muss man sich direkt das C<unicode>-Unterverzeichnis im |
511 |
Perl-Library-Verzeichnis ansehen. Oder den Unicode-Standard, wobei man |
512 |
aber raten muss, wie die entsprechende Klasse in Perl heißt. Oder was die |
513 |
Zeichenklasse macht. |
514 |
|
515 |
Ein weiteres, nützliches Escape-Zeichen ist C<\X>, das passt auf ein |
516 |
Unicode-Zeichen inklusive darauffolgender Akzente oder ähnlicher Zeichen |
517 |
(sogenannte "combining chars", C<n> + (combining) C<~> == C<ñ>). |
518 |
|
519 |
H1: Ausblick |
520 |
|
521 |
Was wird sich noch tun? Nun, zum einen wird die Restriktion auf |
522 |
UTF-8/nicht-UTF-8 entschärft. Es gibt keinen Grund, {{ausschließlich}} |
523 |
UTF-8 zuzulassen. Wenn man schon jedes Unicode-Zeichen in Bezeichnern |
524 |
zulässt, dann sollte das auch in jeder Kodierung möglich sein. |
525 |
|
526 |
Ebenso sollte die interne Repräsentation nicht mehr so stark |
527 |
hervortreten, so dass man später nur noch zwischen "Bytes" und "Zeichen" |
528 |
unterscheidet. Wie das genau aussehen soll, ist mir nicht klar, es scheint |
529 |
mir sehr kompliziert. |
530 |
|
531 |
Das wichtigste sind die sog. "line disciplines", von denen man sich |
532 |
sehr viel Arbeitserleichterung erhoffen kann: Da die meisten Daten doch |
533 |
irgendwann über ein Filehandle gelesen (oder geschrieben) werden, |
534 |
kann man an dieser Stelle zweckmäßigerweise eine Konvertierung |
535 |
durchführen. Das funktioniert natürlich nicht bei "Dateien", auf |
536 |
denen Binär- und Textdaten gemischt werden (also fast alle, man |
537 |
denke z.B. an die Netzwerkverbindung zur Datenbank ;). Ja, liebe |
538 |
Unix-Freunde: C<binmode> wird auch Unix treffen, erschlagen und nie wieder |
539 |
weiterziehen. |
540 |
|
541 |
A1: Links |
542 |
|
543 |
* RFC 2279: UTF-8, a transformation format of ISO 10646 |
544 |
* {{C:perldoc charnames}} - Zeichennamen |
545 |
* {{C:perldoc perlunicode}} - was geht alles NICHT? |
546 |
* C<PERL5LIB/unicode/*> - Unicode Dateien |
547 |
* C<http://www.unicode.org/>, der Unicode-Standard |
548 |
|
549 |
|
550 |
|
551 |
|
552 |
|