umlaute bei Split-Funktion zu nicht lesbar!

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
tco95ttocs
User
Beiträge: 18
Registriert: Mittwoch 1. April 2009, 15:52

Hab ein Problem,
hab wie nicht anders zu erwarten ein Shapefile, bei dem eine Attriputspalte zum größten Teil komplett in Großbuchstaben geschrieben ist. Ich möchte nun die Wörter mit ordenltichen, sprich mit Groß-und Kleinschreibung beachtenden Wörtern ersetzen. Auslesen, und schreiben funktioniert 1a allerdings hab ich Probleme bei den Umlauten.
Wenn ich nen string hab ist alles bestens, allerdings muss ich diesen aufsplitten, da jedes Wort einzeln bearbeitet werden muss:

z.b.: "DAS KLEINE HAUS ist GRÜN" soll "Das kleine Haus ist grün" werden.

allerdings wird immer nur "Das kleine Haus ist GrÜN" daraus, da das Ü nach dem splitten als \xdc erkannt wird. Wie kann ich den split befehl nun dazu bringen das Ü richtig einzulesen?

P.S: \xdc ist ISO-8859-1

hier noch ein Testcodeschnipsel bei dem das Split was anders macht als es soll:

Code: Alles auswählen

# -*- coding: iso-8859-1 -*-

import sys, re

p = re.compile('(\W+)')
k=""
string = "DAS KLEINE HAUS ist GRÜN"
print string
print p.split(string)
for b in range(len(p.split(string))):
    if p.split(string)[b].istitle() and z==0:
        k = k+p.split(string)[b]
    elif p.split(string)[b].islower() and z==0:
        k = k+p.split(string)[b]
    elif z==1:
        k = k+p.split(string)[b].capitalize()
        z=0
    else:
        k = k+p.split(string)[b].capitalize()
    print k
Wie kann ich den split befehl nun dazu bringen das Ü und die anderen Umlaute richtig einzulesen?

Ergebnis von Split:

Code: Alles auswählen

['DAS', ' ', 'KLEINE', ' ', 'HAUS', ' ', 'ist', ' ', 'GR', '\xdc', 'N']
Benutzeravatar
mq
User
Beiträge: 124
Registriert: Samstag 1. Januar 2005, 19:14

Wieso splittest du mit einem Regex? str.split() würde an der Stelle doch völlig reichen.
Wenn du unbedingt Regexes nutzen willst, fütter einen Unicode-String rein und setz das UNICODE-Flag für den Regex.

Oh, und wenn du Codesnippets postest, solltest du sie vorher mal testen, deins crasht nämlich ;)
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Das ist fast das selbe Problem wie in deinem letzten Thread. Du verwendest zwei verschiedene Encodings. Lies dir doch mal das Tutorial dazu durch: http://docs.python.org/howto/unicode.html , dann klappts auch mit dem Sonderzeichen ;)

BTW:
In ISO 8859-1 gibt's kein ü
tco95ttocs
User
Beiträge: 18
Registriert: Mittwoch 1. April 2009, 15:52

also bei mir funzt der schnipsel mit python 2.4.1

jo mit str.split() gehts auch, allerdings hab ich auch das Problem, dass ich noch sonderzeichen mit drin hab, wie /,()- und wenn diese dann direkt vor nem Wort sind, wie z.b. "/BLAU" wird dann antelle von "/Blau" "/blau" nur wenn vorher schon "/Blau" dasteht wird dann auch "/Blau" drauß!

das versteh ich aber eben nicht so ganz!

@fabron: komisch nur, dass all meine Shapefiles in diesem standard sind und alle üöä etc. besitzen ;) und auch beim öffnen mit OO Tabellenkalk ist dieser Standard der einzige, der alles so anzeigt!
und die seite hab ich mir schon mehrmals durchgelesen und auch die beispiele unten getestet, aber sobald da mal ein split rein kommt ist bis jetzt sendepause!

vll. muss ich doch auf das str.split übergehn und mir zusätzlich was für die sonderzeichen überlegen
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Richtich, das mit dem ü war wohl falsch eingeordnet. Hast du dein Skript denn auch in ISO Schnippel gespeichert? Denn irgendwo ist ja wohl ein Mismatch, sonst würdest du den ü auch im split bekommen.

Nachtrag aus dem Tutorial
Latin-1, also known as ISO-8859-1, is a similar encoding. Unicode code points 0-255 are identical to the Latin-1 values, so converting to this encoding simply requires converting code points to byte values; if a code point larger than 255 is encountered, the string can’t be encoded into Latin-1.
und
If the code point is <128, it’s represented by the corresponding byte value.
If the code point is between 128 and 0x7ff, it’s turned into two byte values between 128 and 255.
Code points >0x7ff are turned into three- or four-byte sequences, where each byte of the sequence is between 128 and 255.
Dein ü liegt halt über der 128er Grenze, und die anderen darunter. Deshalb bekommst du da halt keinen Grissel zu sehen
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

tco95ttocs hat geschrieben:allerdings wird immer nur "Das kleine Haus ist GrÜN" daraus, da das Ü nach dem splitten als \xdc erkannt wird. Wie kann ich den split befehl nun dazu bringen das Ü richtig einzulesen?
Das Ü wird schon richtig erkannt, bloß tut ``print beliebige_liste`` nicht das, was du denkst. Die Elemente einer Liste werden mittels ``repr`` in Strings umgewandelt. Vergleiche einfach mal die Ausgabe von ``print string`` mit der von ``print repr(string)``.
Wie kann ich den split befehl nun dazu bringen das Ü und die anderen Umlaute richtig einzulesen?

Ergebnis von Split:

Code: Alles auswählen

['DAS', ' ', 'KLEINE', ' ', 'HAUS', ' ', 'ist', ' ', 'GR', '\xdc', 'N']
Du solltest dir in diesem Fall mal die Doku zu ``re``, speziell die zu \W durchlesen. Setzte das LOCALE-Flag. Oder verwende gleich Unicode ``(string.encode("latin1"))``, dann klappt auch die Groß- und Kleinschreibung von Umlauten vernünftig.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Code: Alles auswählen

#encoding: utf-8
import re
print re.split("(?u)\W+",  u"Preußen überfiel 1740 Österreich")
Geht natürlich auch mit anderem Encoding, aber mein Textmate nutzt nun mal UTF-8. Man beachte das `(?u)` welches dem regulären Ausdruck sagt, dass \w und \W nicht nur A-Z sondern auch Buchstaben des Unicode-Zeichensatz berücksichtigen sollen. Was da als Buchstabe gilt, kann man nachlesen. Und natürlich sollte dann auch der Eingabestring ein Unicode-String sein wie man bei Python eigentlich immer mit u-Strings arbeiten sollte, wenn man nicht gerade Bytearrays meint.

Stefan
tco95ttocs
User
Beiträge: 18
Registriert: Mittwoch 1. April 2009, 15:52

@sma: dein Beispiel ist ganz gut, allerdings bringt mir dies in sofern nix, da ich auch Sonderzeichen, wie ,.-/() habe und diese dann einfach wegfallen.

im moment ist es halt so, dass ich, wenn ich str.split() nehm etwa 20 verschiedene Fälle für Sondereichen benötige, bei re.split() brauch ich das nicht, allerdings ist da das Problem mit den Umlauten.

Edit:

wenn ich die Zeile:

Code: Alles auswählen

print re.split("(?u)\W+",  u"Preußen überfiel 1740 Österreich")
in:

Code: Alles auswählen

print re.split("(?u)(\W+)",  u"Preußen überfiel 1740 Österreich")
änder funktionieren auch die Sonderzeichen.
Das sieht doch sehr danach aus, wie ich es benötige.
Allerdings hab ich in der Doku das ?u nicht gefunden, sondern nur das ?, denk aber mal, dass das u was mit unicode zu tun hat!
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Deinen Code kann man auch noch ordentlich kürzen:

Code: Alles auswählen

splitted = p.split(string)

for element in splitted:
    if not ((element.istitle() or element.islower()) and z==0):
        element =  element.capitalize()
        if z == 1:
            z = 0
    
    k = k + element
Das Leben ist wie ein Tennisball.
tco95ttocs
User
Beiträge: 18
Registriert: Mittwoch 1. April 2009, 15:52

ja das mit dem kürzen hab ich schon gesehen, aber danke für die info :)
Antworten