Die Programmiersprache Ruby (German Edition)
die Methoden des Moduls
Enumerable
, die verwendet werden können, um die Zeilen eines String zu verarbeiten. Sie können in Ruby 1.8 den Iterator
each_byte
verwenden, um über die Bytes eines String zu iterieren, aber dies hat keinen Vorteil gegenüber dem Operator
[]
, weil der Zugriff auf Bytes in beliebiger Reihenfolge in 1.8 genauso schnell ist wie der sequenzielle Zugriff.
In Ruby 1.9 ist die Situation völlig anders, da die Methode
each
entfernt wurde und die Klasse
String
nicht mehr
Enumerable
ist. Anstelle von
each
definiert Ruby 1.9 drei klar benannte String-Iteratoren:
each_byte
iteriert sequenziell über die einzelnen Bytes, aus denen ein String besteht;
each_char
iteriert über die Zeichen und
each_line
über die Zeilen. Wenn Sie einen String zeichenweise verarbeiten möchten, kann es effizienter sein,
each_char
zu verwenden (statt den Operator
[]
und Zeichen-Indizes):
s = "¥1000"
s.each_char {|x| print "#{x} " } # Gibt "¥ 1 0 0 0" aus. Ruby 1.9
0.upto(s.size-1) {|i| print "#{s[i]} "} # Ineffizient mit Mehrbyte-Zeichen
3.2.6 String-Kodierungen und Multibyte-Zeichen
Strings sind in Ruby 1.8 und Ruby 1.9 grundlegend unterschiedlich:
In Ruby 1.8 sind Strings eine Abfolge von Bytes. Wenn Strings verwendet werden, um Text (statt binäre Daten) darzustellen, geht Ruby davon aus, dass jedes Byte des String ein einzelnes ASCII-Zeichen darstellt. In 1.8 sind die einzelnen Elemente eines String keine Zeichen, sondern Zahlen – der tatsächliche Bytewert oder die Zeichenkodierung.
In Ruby 1.9 sind Strings dagegen echte Abfolgen von Zeichen, und diese Zeichen sind nicht auf den ASCII-Zeichensatz beschränkt. In 1.9 sind die einzelnen Elemente eines String Zeichen – dargestellt als Strings der Länge 1 – und keine Integer-Zeichencodes. Jeder String hat eine Kodierung, die die Zuweisung der Bytes im String zu den von ihnen dargestellten Zeichen festlegt. Kodierungen wie die UTF-8-Kodierung von Unicode-Zeichen verwenden variable Anzahlen von Bytes für jedes Zeichen, und es gibt keine 1-zu-1- (oder auch nur 2-zu-1-)Übereinstimmung zwischen Bytes und Zeichen mehr.
Die nachfolgenden Unterabschnitte erläutern die Kodierungsfeatures von Strings in Ruby 1.9 und zeigen auch die rudimentäre Ruby-1.8-Unterstützung für Mehrbyte-Zeichen mithilfe der Bibliothek
jcode
.
3.2.6.1 Mehrbyte-Zeichen in Ruby 1.9
In Ruby 1.9 wurde die Klasse
String
so umgeschrieben, dass sie Mehr-Byte-Zeichen enthalten und korrekt damit umgehen kann. Die Mehr-Byte-Unterstützung ist zwar die größte Änderung in Ruby 1.9, aber keine stark sichtbare Änderung: Code, der Mehr-Byte-Strings verwendet, funktioniert einfach. Es ist jedoch wichtig zu wissen, warum er funktioniert, und dieser Abschnitt erläutert die Details.
Wenn ein String Mehr-Byte-Zeichen enthält, dann entspricht die Anzahl der Bytes nicht der Anzahl der Zeichen. In Ruby 1.9 geben die Methoden
length
und
size
die Anzahl der Zeichen in einem String zurück, während die neue Methode
bytesize
die Anzahl der Bytes liefert:
# -*- coding: utf-8 -*- # Unicode-UTF-8-Zeichen festlegen
# Ein String-Literal mit einem Mehr-Byte-Multiplikationszeichen:
s = "2∞2=4"
# Der String enthält 6 Byte, die fünf Zeichen kodieren
s.length # => 5: Zeichen: '2' '∞' '2' '=' '4'
s.bytesize # => 6: Byte (hex): 32 c3 97 32 3d 34
Beachten Sie, dass die erste Zeile in diesem Code ein Coding-Kommentar ist, der die Quellkodierung UTF-8 festlegt (siehe „2.4.1 Die Programmkodierung festlegen“ ). Ohne diesen Kommentar wüsste der Ruby-Interpreter nicht, wie er die Byte-Sequenz im String-Literal in eine Sequenz von Zeichen umwandeln soll.
Wenn ein String Zeichen enthält, die mit variierender Byte-Anzahl kodiert sind, ist es in dem String nicht mehr möglich, den Zeichenindex direkt einem Byte-Offset zuzuordnen. Im obigen String beginnt das zweite Zeichen beispielsweise beim zweiten Byte. Das dritte Zeichen beginnt dagegen beim vierten Byte. Das bedeutet, dass Sie nicht davon ausgehen können, dass der Zugriff auf beliebige Bytes innerhalb eines String eine schnelle Operation ist. Wenn Sie den Operator
[]
für den Zugriff auf ein Zeichen oder einen Teil-String innerhalb eines Mehr-Byte-String verwenden, dann muss die Ruby-Implementierung intern sequenziell über den String iterieren, um den gewünschten Zeichenindex zu finden. Im Allgemeinen sollten Sie daher versuchen, Ihre String-Verarbeitung mithilfe sequenzieller Algorithmen durchzuführen, wo immer es möglich ist. Das heißt: Verwenden Sie
Weitere Kostenlose Bücher