irgendwo, irgendwann, hab ich mal eine elegant formuliert Schleife
gesehen, die über die Codepoints eines Strings iterierte.
z.B. sowas:
String s = "...";
StringBuilder sb = new StringBuilder();
for (int i=0; i<s.length(); i = nextCodePoint(s,i))
{
int cp = s.codePointAt(i);
cp = Character.toLowercase(cp);
sb.appendCodePoint(cp);
}
Dumm nur, dass es sowas wie "nextCodePoint" nicht gibt. Es soll die
Variable i wahlweise um 1 oder 2 inkrementieren und den Wert zurückgeben.
Sowas, oder sowas in der Art, muss es doch irgendwo geben, sowas man
eine for-schleife über die Codepoints eines Strings elegant schreibt kann.
Ich bin der Meinung, ich habe sowas damals gesehen, und bin jetzt zu
blöd, dass wieder zu finden. Ich such mich grade in den Dokus der
Klassen String und Character dumm und dämlich und seh den Wald vor
lauter Bäumen nicht.
Kann mir jemand weiterhelfen?
Grüße,
Sven
> for (int i=0; i<s.length(); i = nextCodePoint(s,i))
...; i = s.offsetByCodePoints(i, 1))
Gruß, Tor
Genau das!
Danke!
Hmm. Also mir gefällt
for (int cp,i = 0; i<s.length(); i+=Character.charCount(cp)) {
cp = s.codePointAt(i);
... // do whatever u want, but don't change 'cp'
... // as was done in the OP
}
besser; jedenfalls solange der Offset konstant eins beträgt.
>> for (int i=0; i<s.length(); i = nextCodePoint(s,i))
>
> ...; i = s.offsetByCodePoints(i, 1))
Ich kleb hier immer noch auf dem Stand von 1.1 - was zum Teufel sind
"Codepoints" in java.lang.String?
Bernd
--
Visit http://www.nixwill.de and http://www.spammichvoll.de
>Ich kleb hier immer noch auf dem Stand von 1.1 - was zum Teufel sind
>"Codepoints" in java.lang.String?
aus http://java.sun.com/javase/6/docs/api/java/lang/Character.html
>Unicode Character Representations
>
>The char data type (and therefore the value that a Character object
>encapsulates) are based on the original Unicode specification, which
>defined characters as fixed-width 16-bit entities. The Unicode standard
>has since been changed to allow for characters whose representation
>requires more than 16 bits. The range of legal code points is now U+0000
>to U+10FFFF, known as Unicode scalar value. (Refer to the definition of
>the U+n notation in the Unicode standard.)
>
>The set of characters from U+0000 to U+FFFF is sometimes referred to as
>the Basic Multilingual Plane (BMP). Characters whose code points are
>greater than U+FFFF are called supplementary characters. The Java 2
>platform uses the UTF-16 representation in char arrays and in the String
>and StringBuffer classes. In this representation, supplementary characters
>are represented as a pair of char values, the first from the
>high-surrogates range, (\uD800-\uDBFF), the second from the low-surrogates
>range (\uDC00-\uDFFF).
>
>A char value, therefore, represents Basic Multilingual Plane (BMP) code
>points, including the surrogate code points, or code units of the UTF-16
>encoding. An int value represents all Unicode code points, including
>supplementary code points. The lower (least significant) 21 bits of int
>are used to represent Unicode code points and the upper (most significant)
>11 bits must be zero. Unless otherwise specified, the behavior with
>respect to supplementary characters and surrogate char values is as
>follows:
>
> * The methods that only accept a char value cannot support supplementary characters. They treat char values from the surrogate ranges as undefined characters. For example, Character.isLetter('\uD840') returns false, even though this specific value if followed by any low-surrogate value in a string would represent a letter.
> * The methods that accept an int value support all Unicode characters, including supplementary characters. For example, Character.isLetter(0x2F81A) returns true because the code point value represents a letter (a CJK ideograph).
>
>In the Java SE API documentation, Unicode code point is used for character
>values in the range between U+0000 and U+10FFFF, and Unicode code unit is
>used for 16-bit char values that are code units of the UTF-16 encoding.
>For more information on Unicode terminology, refer to the Unicode Glossary.
LOL ...
Also man hat festgestellt, dass die Grenzen von UCS2 gesprengt sind.
Früher war ein String ein UCS2 String. Jetzt ist ein String ein UTF-16
String. Denn es gibt in der Unicode-Spec jetzt Zeichen mit einer Nummer
>0xFFFF und damit ist der Wertebereich von char gesprengt.
Ja und da hat sich Sun gedacht, dass sie jetzt wohl UTF-16 benutzen
müssen. Ja und das tun sie jetzt auch. Und damit gelten jetzt folgende
Regeln:
1 logisches Zeichen == 1 codepoint
1 codepoint == 1 bis 2 chars
Früher galt mal:
1 logisches Zeichen == 1 char
Aber die Zeiten sind vorbei.
Codepoints werden als int gespeichert. Deswegen gibt es jetzt z.B. neben
Character.toLowerCase(char) auch ein Character.toLowerCase(int).
Und das Iterieren über die logischen Zeichen eines Strings muss jetzt
über Codepoints erledigt werden.
Würde man also einen String manuell nach UTF-8 umwandeln wollen, dann
wäre es das fälscheste vom falschen, einfach eine Schleife über die
chars zu machen. Statt dessen muss man eine Schleife über die Codepoints
machen, um die integer Werte nach UTF8-Manie zerlegen.
Ja so ist das - Java wird alt.
Grüße,
Sven
>>Ich kleb hier immer noch auf dem Stand von 1.1 - was zum Teufel sind
>>"Codepoints" in java.lang.String?
>
> aus http://java.sun.com/javase/6/docs/api/java/lang/Character.html
Oh, sorry - offensichtlich falsche Fragestellung meinerseits.
Neue Frage: Was macht man mit Codepoints, denn zum Essen sind sie
offensichlich nicht geeignet.
Wenn es was obskures ist womit nur Griechen aus den Quellen schöpfen
können sagt einfach "brauch ich nicht" :-)
> Früher galt mal:
>
> 1 logisches Zeichen == 1 char
>
> Aber die Zeiten sind vorbei.
Ok, soweit verstanden.
An welcher Stelle muss ich nun eingreifen?
Bislang hab ich es nur mit den Traditionellen UTF Bereichen (Abkömmlinge
von indogermanischen Sprachen und deren Abkömmlinge wie Germanisch,
Latein, Indisch sowie Thai, Vietnamesisch, Japanisch und Mandarin zu tun
gehabt).
Muss ich jetzt jedes .charAt(..) untersuchen und auf Codepoints umbasteln?
>Neue Frage: Was macht man mit Codepoints, denn zum Essen sind sie
>offensichlich nicht geeignet.
Fast alle Fragen zu Code Points sollten eigentlich hier beantwortet sein:
http://java.sun.com/developer/technicalArticles/Intl/Supplementary/
so zum Beispiel auch deine letzte:
>Supporting Supplementary Characters in Your Application
>Now, the question that matters most to most readers: What changes do you
>have to make to your application in order to support supplementary
>characters?
>
>The answer depends on what kind of text processing is done within the
>application and which Java platform APIs are used.
>
>Applications that deal with text only in the form of char sequences in all
>forms (char[], implementations of java.lang.CharSequence, implementations
>of java.text.CharacterIterator), and only use Java APIs that accept and
>return such char sequences, will likely not have to make any changes. The
>implementation of the Java platform APIs should handle supplementary
>characters for you.
>
>Applications that interpret individual characters themselves, pass
>individual characters to Java platform APIs, or call methods that return
>individual characters, need to consider the valid values for these
>characters. In many cases it turns out that support for supplementary
>characters is not required. For example, if an application scans a char
>sequence for HTML tags, checking each char individually, it knows that
>these tags only use characters from the Basic Latin block. If the text
>being scanned contains supplementary characters, then these characters
>cannot be confused with the tag characters, because UTF-16 represents
>supplementary characters using code units whose values are not used for
>BMP characters.
>
>Only where applications interpret individual characters themselves, pass
>individual characters to Java platform APIs, or call methods that return
>individual characters, and these character can be supplementary
>characters, does the application have to be changed. Where parallel APIs
>are available that use char sequences, it is best to convert to use such
>APIs. In the remaining cases, it will be necessary to use the new API to
>convert between char and code point-based representations, and call code
>point-based APIs. Unless, of course, you're lucky and find that there are
>newer and more convenient APIs in J2SE 5.0 that let you support
>supplementary characters and simplify your code at the same time, as in
>the formatting sample above.
>
>You might wonder whether it's better to convert all text into code point
>representation (say, an int[]) and process it in that representation, or
>whether it's better to stick with char sequences most of the time and only
>convert to code points when needed. Well, the Java platform APIs in
>general certainly have a preference for char sequences, and using them
>will also save memory space.
>
>For applications that need conversion to and from UTF-8 you will also need
>to consider carefully whether standard or modified UTF-8 is required, and
>use the proper Java platform facilities for each. The section "Modified
>UTF-8" provides the information needed to choose the right one.
Auf dieses Dokument wird übrigens von hier aus verwiesen:
http://java.sun.com/j2se/1.5.0/docs/relnotes/features.html
und darauf wiederum von hier aus:
http://java.sun.com/j2se/1.5.0/docs/
Nur um mal zu zeigen. wie man solche Infos selbst finden kann.
Das kann ich dir nicht sagen.
Besondern wenn man einzelne Zeichen manipuliert - toLowerCase oder sowas.
Guck einfach, wo du noch die alten bösen toLowerCase(char) und Kollegen
anstatt der neuen toLowerCase(int) benutzt.
Von den Sprachen hab ich keine Ahnung - musst du mal gucken, was da oben
im Unicode bereich jenseits von 0xFFFF so rumgammelt. Kann sein, dass es
nur mit chinesisch und solchen Dingen zu tun hat. Aber nix genaues weiss
ich nicht.
Grüße,
Sven
> Nur um mal zu zeigen. wie man solche Infos selbst finden kann.
Das einzige, was gezeigt wurde war dass Du eine Suchmaschine und Deine
Bookmarks bedienen kannst.
Du hast aber nicht gezeigt, dass Du ein Wort von dem von Dir zitierten
Text verstanden bzw. schonmal in der Praxis umgesetzt hast.
Hättest Du das, hätte Deine Antwort nicht in einem Quote ausgefallen.
Und wenn wir in dieser Newsgroup nur noch Quotes oder gar www.gidf.de
statt Erfahrungswerte und "best practice" als Antworten geben, dann
bestimme ich Dich gerne als denjenigen, der freudig das Licht ausmachen
darf.
ids,
Bist du sicher, dass du codepoints meinst? die sind bei UTF-8 immer 2 lang.
http://itblog.eckenfels.net/archives/17-Java-und-Unicode.html
Gruss
Bernd
> Guck einfach, wo du noch die alten bösen toLowerCase(char) und Kollegen
> anstatt der neuen toLowerCase(int) benutzt.
Ist nicht so einfach wegen Rückwärtskompatibilität (ich muss hier bis
auf hoffentlich absehbare Zeit noch 1.1 unterstützen).
> Von den Sprachen hab ich keine Ahnung - musst du mal gucken, was da oben
> im Unicode bereich jenseits von 0xFFFF so rumgammelt. Kann sein, dass es
> nur mit chinesisch und solchen Dingen zu tun hat. Aber nix genaues weiss
> ich nicht.
Der Tip mit 0xFFFF war schonmal gut.
Mit 08/15 Java bewegen wir uns "nur" auf Block/Plane/Ebene 0 von Unicode
16bit und damit kann ich mit den bestehenden Programmen sowas nettes wie
"Arabische Ligatur Lam-Alif mit untergesetztem Hamza Finalform"
darstellen (insch'allah).
Unicode über 0xFFFF werde ich zumindest in unserer Anwendungssoftware
wohl nie anfassen müssen und der Rest ist eh Sonderprogrammierung.
Sich wieder schlafen legend,
Du meinst ohne selbst auf die Surrogat Bereiche zu testen? Weiss ich jetzt
nicht, aber es gibt ja auch noch: offsetByCodePoints()
Oft sollte man die Schleifen vermeiden (also in deinem Fall str.toLower()
oder im Fall von Zeichenweiser Suche kann man indexOf(String) verwenden.
Das hatte ich hier mal geschrieben:
http://itblog.eckenfels.net/archives/17-Java-und-Unicode.html
Gruss
Bernd
1-2 code units (in Java als native char gespeichert)
Gruss
Bernd
Oder String.toLowerCase!
Gruss
Bernd
>Ralf Ullrich schrieb:
>
>>Nur um mal zu zeigen. wie man solche Infos selbst finden kann.
>
>Das einzige, was gezeigt wurde war dass Du eine Suchmaschine und Deine
>Bookmarks bedienen kannst.
>
>Du hast aber nicht gezeigt, dass Du ein Wort von dem von Dir zitierten
>Text verstanden bzw. schonmal in der Praxis umgesetzt hast.
Süß. Du kennst mich (noch) nicht, nicht wahr?
>Hättest Du das, hätte Deine Antwort nicht in einem Quote ausgefallen.
>
>Und wenn wir in dieser Newsgroup nur noch Quotes oder gar www.gidf.de
>statt Erfahrungswerte und "best practice" als Antworten geben, dann
>bestimme ich Dich gerne als denjenigen, der freudig das Licht ausmachen
>darf.
Weißt', was ich an der JavaSE-Welt so schön finde?
Dass praktisch alles genauestens spezifiert ist und oft genug noch
darüberhinaus an zwei oder drei Stellen dokumentiert. Eigentlich braucht
man bloß die Dokus alle lesen, und schon hätte man gar keine doofen Fragen
mehr nötig. Und ja, genau deswegen sind Web-Verweise und Quotes das beste
Mittel PRAXISWISSEN weiterzugeben, denn
1. beantworten sie die Fragen
und
2. zeigen sie wo man weitere Antworten auf weitere Fragen finden könnte.
Und solange die Dokus bereits die Best Practices enthalten und Links und
Quotes damit ebenfalls die komplette Antwort enthalten, sehe ich keinen
Anlass mir eigene (möglicherweise sogar fehlerhafte) Texte einfallen zu
lassen.
cu
>>Du hast aber nicht gezeigt, dass Du ein Wort von dem von Dir zitierten
>>Text verstanden bzw. schonmal in der Praxis umgesetzt hast.
>
> Süß. Du kennst mich (noch) nicht, nicht wahr?
Hm... Nein, ich kenne Dich (noch) nicht.
Darf ich mich vorstellen: Bernd Hohmann, Landprogrammierer.
Geboren 11.10.1966.
Informatikstudium zugunsten der Organisationsprogrammierung hingeschmissen.
Kann aus dem Stand eine Fibu/Wawi/Lohnprogrammierung in 4 verschiedenen
Programmiersprachen incl. notwendiger Toolboxen in 6 Sprachen neu fertigen.
Verheiratet, zwei halbe Kinder, Haus, Ehefrau und viel Privatleben.
Fragt bevorzugt Kollegen nach Lösungen nach dem KISS Prinzip und wehe
wenn da was kompliziertes angefahren wird.
Und nun Du.
> Neue Frage: Was macht man mit Codepoints, denn zum Essen sind sie
> offensichlich nicht geeignet.
Man kann damit ganz Unicode adressieren. Das ist notwendig, weil die
ursprünglichen 16 Bit mittlerweile ausgegangen sind.
Verdammt, ich wusste es auch nicht,
ich muss meistens Java 1.4 machen.
> Also man hat festgestellt, dass die Grenzen von UCS2 gesprengt sind.
> Früher war ein String ein UCS2 String. Jetzt ist ein String ein UTF-16
> String. Denn es gibt in der Unicode-Spec jetzt Zeichen mit einer Nummer
>
> >0xFFFF und damit ist der Wertebereich von char gesprengt.
>
> Ja und da hat sich Sun gedacht, dass sie jetzt wohl UTF-16 benutzen
> müssen. Ja und das tun sie jetzt auch. Und damit gelten jetzt folgende
> Regeln:
>
> 1 logisches Zeichen == 1 codepoint
> 1 codepoint == 1 bis 2 chars
>
> Früher galt mal:
>
> 1 logisches Zeichen == 1 char
Ich kenne zwar nicht alle Konsequenzen,
aber wäre es nicht besser gewesen,
char aufzubohren und die Problematik
unter dem API zu halten ?
Zum Beispiel ein 32-Bit-char
Dann wäre alter Code eventuell korrekt geblieben.
Und um den Speicher nicht platzen zu lassen,
hätte man unter dem API von String, CharSequence
und was weiss ich UTF-xx, Kompression oder
sonstwas erlaubt, per Paramater oder per interner
Optimierung gesteuert.
> Aber die Zeiten sind vorbei.
> Codepoints werden als int gespeichert. Deswegen gibt es jetzt z.B. neben
> Character.toLowerCase(char) auch ein Character.toLowerCase(int).
>
> Und das Iterieren über die logischen Zeichen eines Strings muss jetzt
> über Codepoints erledigt werden.
>
> Würde man also einen String manuell nach UTF-8 umwandeln wollen, dann
> wäre es das fälscheste vom falschen, einfach eine Schleife über die
> chars zu machen. Statt dessen muss man eine Schleife über die Codepoints
> machen, um die integer Werte nach UTF8-Manie zerlegen.
Ist irgendwie nicht schlauer als beim Übergang
von ASCII/ANSI zu 16bit-Unicode.
Bis Java eben Unicode als Standard
eingebaut hatte.
> Ja so ist das - Java wird alt.
Ja ACK.
> Grüße,
> Sven
Grüsse
Heiner
>> > Ich kleb hier immer noch auf dem Stand von 1.1 - was zum Teufel sind
>> > "Codepoints" in java.lang.String?
>
> Verdammt, ich wusste es auch nicht,
> ich muss meistens Java 1.4 machen.
Wir sind hier auf der Insel der Glückseligen ;-)
> Ich kenne zwar nicht alle Konsequenzen,
> aber wäre es nicht besser gewesen,
> char aufzubohren und die Problematik
> unter dem API zu halten ?
Das hab ich zuerst auch gedacht. Aber wenn man sich die Unicode-Planes
anschaut, die mit der Erweiterung zugänglich gemacht werden, will man
das nicht wirklich dauernd herumschleppen.
> Zum Beispiel ein 32-Bit-char [...]
> Und um den Speicher nicht platzen zu lassen,
> hätte man unter dem API von String, CharSequence
> und was weiss ich UTF-xx, Kompression oder
> sonstwas erlaubt, per Paramater oder per interner
> Optimierung gesteuert.
Hätte seinen Charme, aber ich glaube nicht dass das durchsetzbar wäre.
> Mit 08/15 Java bewegen wir uns "nur" auf Block/Plane/Ebene 0 von Unicode
> 16bit und damit kann ich mit den bestehenden Programmen sowas nettes wie
> "Arabische Ligatur Lam-Alif mit untergesetztem Hamza Finalform"
> darstellen (insch'allah).
Ich lese zu viel Nachrichten. Hab mich gerade gewundert, dass
es fuer die "Hamaz Finalform" schon ein eigenes Zeichen, wo
das Ende des Nahostkonflikts doch noch gar nicht absehbar ist.
Gruesse, Lothar
--
Lothar Kimmeringer E-Mail: spam...@kimmeringer.de
PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)
Always remember: The answer is forty-two, there can only be wrong
questions!
Was ist mit String.toLowerCase?
Die benutzen intern bestimmt die Codepoints - oder sehe ich das flasch?
Darüberhinaus habe ich neulich festgestellt, dass toLowerCase Locale
abhängig ist :-(
> Ich kenne zwar nicht alle Konsequenzen,
> aber wäre es nicht besser gewesen,
> char aufzubohren und die Problematik
> unter dem API zu halten ?
>
> Zum Beispiel ein 32-Bit-char
>
> Dann wäre alter Code eventuell korrekt geblieben.
>
> Und um den Speicher nicht platzen zu lassen,
> hätte man unter dem API von String, CharSequence
> und was weiss ich UTF-xx, Kompression oder
> sonstwas erlaubt, per Paramater oder per interner
> Optimierung gesteuert.
Das Problem ist, dass char nicht als "Unicode-Zeichen",
sondern als 16-bit-Integer definiert war, inklusive der
Rechenoperationen. Und die funktionieren modulo 2^16
nunmal anders als modulo 2^32.
Paul
--
Nun ludigxas: : ()