Umlaute

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.
MarcelF6
User
Beiträge: 226
Registriert: Samstag 3. März 2012, 21:30

Samstag 17. März 2012, 18:39

Hallo liebe Mitglieder,

weiss jemand, was man wie / wo ändern muss, damit python Statements à la:

Code: Alles auswählen

re.sub("ß", "ss", string)
versteht?
Das Problem liegt ja darin, dass nicht-ASCII-Zeichen per default nicht "erkannt" werden...

Danke im Voraus.
Benutzeravatar
cofi
Moderator
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Samstag 17. März 2012, 18:51

Nein, das Problem liegt darin, dass "ß" ein _Bytestring_ ist. `string` also dasselbe Encoding haben muss wie deine Datei damit der Code funktioniert.

Code: Alles auswählen

In [4]: print re.sub('ß', 'ss', u'Straße')
Straße

In [5]: print re.sub(u'ß', 'ss', u'Straße')
Strasse

In [6]: print re.sub(u'ß', 'ss', 'Straße')
Straße

In [7]: print re.sub('ß', 'ss', 'Straße')
Strasse
BlackJack

Samstag 17. März 2012, 19:22

@MarcelF6: Du bekommst da doch ziemlich sicher eine Ausnahme. Wie lautet die denn? Komplett bitte. Hast Du den Text gelesen? Also auch dem Hinweis nachgegangen?
MarcelF6
User
Beiträge: 226
Registriert: Samstag 3. März 2012, 21:30

Samstag 17. März 2012, 21:03

Ja, die Fehlermeldung besagt dass kein encoding definiert wurde. Also:
" [...]on line 17, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details "

Also es geht um folgenden Programmausschnitt:

Code: Alles auswählen

f = file(unicodeObjekt)
    while True:
        out = f.readlines()
        out = out.lower()
        ae = re.sub(u'ä', 'ae', out)
        oe = re.sub(u"ö", "oe", ae)
        ue = re.sub(u"ü", "ue", oe)
        ss = re.sub(u"ß", "ss", ue)
        return ss
    f.close()
So "einfach" wie ich gedacht habe funktioniert das leider nicht. Also gibt es eine andere Möglichkeit das so zu machen wie ich es vor hatte?
lunar

Samstag 17. März 2012, 21:06

@MarcelF6: Lies für den Anfang doch einfach mal die Seite, auf welche in der Fehlermeldung verwiesen wird.
BlackJack

Samstag 17. März 2012, 22:15

@MarcelF6: `re.sub()` ist hier auch etwas mit Kanonen auf Spatzen geschossen. Wenn Du einfach nur statische Zeichenfolgen ersetzen willst, dann gibt es auf Zeichenketten dafür eine einfachere Methode.
EyDu
User
Beiträge: 4872
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Samstag 17. März 2012, 22:27

Mich würde nun aber wirklich stark interessieren, aus welchem Grund du überall diese unnötigen ``while True`` verwendest.
Das Leben ist wie ein Tennisball.
MarcelF6
User
Beiträge: 226
Registriert: Samstag 3. März 2012, 21:30

Samstag 17. März 2012, 22:30

Habe ich gemacht - so wie ich es verstanden habe muss man gewisse encodings vornehmen.
Ich habs mal probiert:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-#

import re
import sys

def funktion(unicodeObjekt):
    '''Gib eine Datei auf der Standardausgabe aus.'''
    f = unicode(file(unicodeObjekt))
    f.unicode.encode('utf-8')
    while True:
        out = f.readlines()
        out = out.lower()
        ae = re.sub(u'ä', 'ae', out)
        oe = re.sub(u"ö", "oe", ae)
        ue = re.sub(u"ü", "ue", oe)
        ss = re.sub(u"ß", "ss", ue)
        return ss
    f.close()

if len(sys.argv) < 2:
    print 'Es wurden keine Parameter übergeben.'
    sys.exit()
else:
    for unicodeObjekt in sys.argv[1:]:
        funktion(unicodeObjekt)
Wie gesagt: "probiert". Das Problem ist, dass ich aus der Beschreibung nicht ganz schlau wurde, was genau wie encodiert werden sollte..

@Blackjack: Ich habe als input einfach ein Unicode-Objekt.

@EyDu: Werd ich noch wegmachen ;) ..hab das eben alles nacheinander geschrieben :)
Zuletzt geändert von MarcelF6 am Sonntag 18. März 2012, 02:59, insgesamt 1-mal geändert.
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

Samstag 17. März 2012, 22:47

- „while True“ ist sinnlos: Du verlässt die Schleife eh im ersten Durchgang.
- Du brauchst immer noch kein re.sub für einfache Substitutionen. „str.replace“ reicht vollkommen.
- „f.close()“ wird nie ausgeführt werden, da du vorher schon die Funktion verlässt.
- Wenn du kein Emacs verwendest kannst du auch „# coding: utf-8“ benutzen.
- Du probierst viel zu wild ‘rum!

Code: Alles auswählen

In [8]: unicode(file('blabla.txt'))
Out[8]: u"<open file 'blabla.txt', mode 'r' at 0x956e5a0>"

In [9]: _.unicode.encode('utf-8') # _ ist u"<open ...>"
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/home/jakob/<ipython-input-9-3480aff0e5da> in <module>()
----> 1 _.unicode # _ ist u"<open ...>"

AttributeError: 'unicode' object has no attribute 'unicode'
Schau dir mal die Seiten aus Hyperions Signatur an, ich finde, dass Unicode und Encodings in Python da sehr gut erläutert werden:
Leonidas’ FolienVon Umlauten, Unicode und Encodings im Wiki — Pragmatic Unicode – Präsentation von Ned Batchelder zu Unicode
Zuletzt geändert von nomnom am Samstag 17. März 2012, 22:49, insgesamt 1-mal geändert.
EyDu
User
Beiträge: 4872
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Samstag 17. März 2012, 22:48

Wie wäre es, wenn du uns auch das Beispiel gibst, mit dem du arbeitest? Ganz offensichtlich existiert die Funktion "normalize" nicht, wahrscheinlich ist "funktion" gemeint.

Folgender Code sieht auf jeden Fall falsch aus:

Code: Alles auswählen

f = unicode(file(unicodeObjekt))
f.unicode.encode('utf-8')
Zerlege das mal in einzelne Schritte und lasse dir die Zwischenergebnisse ausgeben. Den Trick solltest du jetzt ja eignetlich schon kennen.

Zum ``while-True``: Warum entfernst du es nicht bevor du es postest? Um so weniger Code wir lesen müssen, desto wahrscheinlicher ist es, dass dir geholfen wird. Vorallem wenn es um Abschnitte geht, auf die man die bereits hingeweisen hat.
Das Leben ist wie ein Tennisball.
MarcelF6
User
Beiträge: 226
Registriert: Samstag 3. März 2012, 21:30

Sonntag 18. März 2012, 03:27

Danke für die Hilfe.
Also ich hab den Code auch nochmals überarbeitet:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-#

import sys

def funktion(unicodeObjekt):
    '''Gib eine Datei auf der Standardausgabe aus.'''
    with open(unicodeObjekt, "r") as f:
	content = unicode(f.read())
	return string.replace(content, 'ä', 'ae')


if len(sys.argv) < 2:
    print 'Es wurden keine Parameter übergeben.'
    sys.exit()
else:
    funktion(sys.argv[1])
Allerdings hab ich immernoch eine Fehlermeldung:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 8: ordinal not in range(128)
Ich bin mir aber nicht sicher, ob das wirklich ein Problem wegen des Codes ist oder ob die Meldung vom Editor stammt. Denn jetzt reklamiert die shell auch bei normalen print-Statements mit ä,ö,ü dass sie keine ASCII-Characters seien. Woran genau liegt das Problem?
Dankeschön!
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

Sonntag 18. März 2012, 08:55

Wenn du ein „unicode“-Objekt erstellen möchtest und kein Encoding angibst, dann wird angenommen, dass ASCII verwendet wurde.

Code: Alles auswählen

    content = unicode(f.read())
Du musst wissen, in welchem Encoding deine Datei vorliegt und dann

Code: Alles auswählen

f.read().encode('*encoding*')
aufrufen.

Code: Alles auswählen

    return content.replace(u'ä', u'ae') # ist übrigens "besser" als string.replace, vor allem wenn man string gar nicht importiert
BlackJack

Sonntag 18. März 2012, 09:05

@nomnom: Du meinst sicher `decode()` nach dem einlesen…

@MarcelF6: Die Kodierungsprobleme beim ``print`` könnten daran liegen, dass Du versuchst `unicode`-Objekte auszugeben ohne sie vorher in `str` zu konvertieren. Und zwar mit der Kodierung die das Programm erwartet, dass die Zeichen dann darstellen soll.
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

Sonntag 18. März 2012, 09:33

BlackJack hat geschrieben:@nomnom: Du meinst sicher `decode()` nach dem einlesen…
Ja, meinte ich … :oops:
MarcelF6
User
Beiträge: 226
Registriert: Samstag 3. März 2012, 21:30

Sonntag 18. März 2012, 11:24

Danke euch beiden für die Hilfe.
@nomnom: Hast du es so gemeint? :

Code: Alles auswählen

def funktion(unicodeObjekt):
    '''Gib eine Datei auf der Standardausgabe aus.'''
    with open(unicodeObjekt, "r") as f:
	content = unicode(f.read().decode('utf-8'))
	return content.replace(u'ä', u'ae')
Antworten