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äöü&#8364;"

Das geht auch mit utest.encode("latin-1", "xmlcharrefreplace")

[...]

Bis demnächst,
    Walter Dörwald