Re: [Python-de] Unicode - ein Vorschlag zur Güte
Walter Dörwald
walter at livinglogic.de
Fre Jan 2 12:46:18 CET 2004
Georg Mischler wrote:
> def flex_encode(u, enc='iso-8859-1', replace=None, fmt=None):
> if replace != None and fmt != None:
> raise ValueError, '"replace" und "fmt" nur einzeln zulaessig'
> if type(u) == type(''): return u # potentiell gefaehrlich!
> try: return u.encode(enc)
> except UnicodeError:
> sl = []
> for uc in u:
> o = ord(uc)
> if o < 128: # ascii
> sl.append(chr(o))
> else:
> try: sl.append(uc.encode(enc)) # passt in's charset
> except UnicodeError:
> if replace:
> sl.append(replace) # ersetzen
> elif fmt:
> sl.append(fmt % ord(uc)) # konvertieren
> return ''.join(sl)
Diese beiden Methoden (replace und fmt) lassen sich auch über
den neuen Codec-Error-Callback-Mechanismus von 2.3 lösen
(siehe PEP 293):
class Replace(object):
def __init__(self, replace):
self.replace = replace
def __call__(self, exc):
return (self.replace*(exc.end-exc.start), exc.end)
class Fmt(object):
def __init__(self, fmt):
self.fmt = fmt
def __call__(self, exc):
return (self.fmt % ord(exc.object[exc.start]), exc.start+1)
import codecs
codecs.register_error("gmreplace", Replace(u"XXX"))
codecs.register_error("gmfmt", Fmt(u"\\x%x"))
utest = u'abc\xe4\xf6\xfc\u20ac'
>>> utest.encode("latin-1", "gmreplace")
'abc\xe4\xf6\xfcXXX'
>>> utest.encode("latin-1", "gmfmt")
'abc\xe4\xf6\xfc\\x20ac'
>>>>print flex_encode(utest) # unpassende zeichen ignorieren
>
> "abcäöü"
>
>>>>print flex_encode(utest, replace='?') # ersetzen
>
> "abcäöü?"
>
>>>>print flex_encode(utest, fmt='\\x%x') # konvertieren
>
> "abcäöü\x20ac"
>
> # fuer HTML:
>
>
>>>>print flex_encode(utest, fmt='&#%d;')
>
> "abcäöü€"
Das geht auch mit utest.encode("latin-1", "xmlcharrefreplace")
[...]
Bis demnächst,
Walter Dörwald