Seite 1 von 1
UTF-8 hexadezimal -> Zeichen
Verfasst: Freitag 30. Juli 2010, 14:01
von aurikeL
Hallo Forum,
ich stehe zurzeit vor einem Problem, welches mich leicht stört. Ich habe mehrere Strings, die zB. so aussehen "M(c3bc)ll". Mein Ziel ist es nun, dass der String so aussieht: "Müll". Die Klammern stellen (natürlich) kein Problem dar, allerdings weiß ich nicht, wie ich das C3 BC zu einem "ü" umwandle - ich hab bisher folgendes herausgefunden: bei dem C3 BC handelt es sich um
UTF-8 hexadezimal. Wisst ihr einen Rat?
(Python-Version: 2.3)
Gruß,
Max
Re: UTF-8 hexadezimal -> Zeichen
Verfasst: Freitag 30. Juli 2010, 14:26
von /me
aurikeL hat geschrieben:[...], allerdings weiß ich nicht, wie ich das C3 BC zu einem "ü" umwandle
Mit Python 2.6 (antike Versionen stehen mir nicht zur Verfügung) erhalte ich hiermit ein "ü":
Code: Alles auswählen
# -*- coding: utf-8 -*-
from __future__ import print_function
x1 = chr(0xC3)
x2 = chr(0xBC)
print(x1, x2)
a = x1 + x2
print(a)
Re: UTF-8 hexadezimal -> Zeichen
Verfasst: Freitag 30. Juli 2010, 14:31
von ms4py
Ja, das geht. Hab es etwas umständlich gelöst, vielleicht geht das noch besser:
Code: Alles auswählen
>>> c = 'c3bc'
>>> s = chr(int('0x%s' % c[:2], 16)) + chr(int('0x%s' % c[2:], 16))
>>> print s.decode("utf8")
ü
(Unter 2.6 getestet)
Re: UTF-8 hexadezimal -> Zeichen
Verfasst: Freitag 30. Juli 2010, 14:32
von cofi
Stellt sich die Frage _wo_ du die hexadezimale Darstellung hast (im Allgemeinen sieht die `repr` Darstellung genau so aus, also wenn man z.b. Listen `print`et). Mehr Infos bitte.
Re: UTF-8 hexadezimal -> Zeichen
Verfasst: Freitag 30. Juli 2010, 14:36
von ms4py
cofi hat geschrieben:im Allgemeinen sieht die `repr` Darstellung genau so aus, also wenn man z.b. Listen `print`et
Also unter 2.6 nicht, ist das mit 2.3 so?
Re: UTF-8 hexadezimal -> Zeichen
Verfasst: Freitag 30. Juli 2010, 14:42
von BlackJack
Code: Alles auswählen
import re
def replace_hex(string):
def byte_sub(match):
hex_digits_it = iter(match.group(0)[1:-1])
return ''.join(chr(int(a + b, 16))
for a, b in zip(hex_digits_it, hex_digits_it))
return re.sub(r'\(([0-9a-f]{2})+\)', byte_sub, string)
def main():
old = 'M(c3bc)ll'
new = replace_hex(old)
print new
if __name__ == '__main__':
main()
Re: UTF-8 hexadezimal -> Zeichen
Verfasst: Freitag 30. Juli 2010, 15:51
von aurikeL
cofi hat geschrieben:Stellt sich die Frage _wo_ du die hexadezimale Darstellung hast (im Allgemeinen sieht die `repr` Darstellung genau so aus, also wenn man z.b. Listen `print`et). Mehr Infos bitte.
Danke für eure Antworten, ich werde sie am Montag testen.
An
cofi: Ich lese über os.listdir() alle Ordner in einem bestimmten Verzeichnis aus und erstelle zu jedem Ordner eine neue Datei, dabei möchte ich allerdings, dass die hexadezimale Darstellung von Umlauten/Sondernzeichen(?) ersetzt wird. Ein Ordner würde dann zB. "M(c3bc)ll" heißen - die dazugehörige Datei soll allerdings "Müll" heißen.
Sollte es widererwartend Montag nicht klappen, so melde ich mich nochmal ..
.. schönes Wochenende.

Re: UTF-8 hexadezimal -> Zeichen
Verfasst: Freitag 30. Juli 2010, 15:54
von ms4py
BJ's Snippet etwas vereinfacht:
Code: Alles auswählen
#!/usr/bin/env python
import re
def replace_hex(string):
def byte_sub(match):
return ''.join(chr(int(a, 16)) for a in match.groups())
return re.sub(r'\(([0-9a-f]{2})([0-9a-f]{2})\)', byte_sub, string)
def main():
old = 'M(c3bc)ll'
new = replace_hex(old)
print new
if __name__ == '__main__':
main()
Re: UTF-8 hexadezimal -> Zeichen
Verfasst: Freitag 30. Juli 2010, 15:58
von BlackJack
@ms4py: Etwas zu sehr vereinfacht, denn nicht alle UTF-8 Sequenzen sind nur zwei Bytes lang.
Re: UTF-8 hexadezimal -> Zeichen
Verfasst: Freitag 30. Juli 2010, 17:01
von ms4py
BlackJack hat geschrieben:@ms4py: Etwas zu sehr vereinfacht, denn nicht alle UTF-8 Sequenzen sind nur zwei Bytes lang.
Ja, du hast Recht. Aber in diesem Anwendungsfall müsste es reichen.
Deine `iter`-Lösung finde ich jedenfalls zu magisch. Vielleicht gibt es auch eine bessere Lösung um immer zwei Elemente aus dem String zu nehmen?
Re: UTF-8 hexadezimal -> Zeichen
Verfasst: Freitag 30. Juli 2010, 17:31
von BlackJack
@ms4py: Slicing und über Indexe in Zweierschritten ginge. Andererseits ist so eine "zu magische" Lösung irgendwo in der Python-Doku wenn ich mich recht erinnere.
Re: UTF-8 hexadezimal -> Zeichen
Verfasst: Freitag 30. Juli 2010, 17:43
von ms4py
BlackJack hat geschrieben:@ms4py: Slicing und über Indexe in Zweierschritten ginge. Andererseits ist so eine "zu magische" Lösung irgendwo in der Python-Doku wenn ich mich recht erinnere.
Naja, damit ist auch nicht wirklich besser (oder geht das noch besser?)
Code: Alles auswählen
from itertools import izip
def split_in_two(string):
for a, b in izip(string[::2], string[1::2]):
yield a+b
Bei dir ist diese Funktion eben so "magisch" versteckt.
Auslagern in eine Funktion wäre im Prinzip auch schon in Ordnung

Re: UTF-8 hexadezimal -> Zeichen
Verfasst: Freitag 30. Juli 2010, 17:49
von BlackJack
@ms4py: Ich dachte mehr an sowas:
Code: Alles auswählen
In [464]: list(string[i:i + 2] for i in xrange(0, len(string), 2))
Out[464]: ['c3', 'bc']
Re: UTF-8 hexadezimal -> Zeichen
Verfasst: Samstag 31. Juli 2010, 08:35
von sma
So geht's mit Python 3.x:
Code: Alles auswählen
import re
def decode(s):
return re.sub(r"\(([0-9A-Fa-f]+)\)", lambda m:bytes.fromhex(m.group(1)).decode("utf-8"), s)
print(decode('M(C3BC)ll (C384)rger'))
und für Python 2.x kann das Lambda so aussehen (und der übergebene String sollte natürlich ein echter String sein, d.h. ein "u" vorangestellt bekommen):
Stefan
Re: UTF-8 hexadezimal -> Zeichen
Verfasst: Samstag 31. Juli 2010, 09:22
von snafu
@ms4py:
Das kommt dir vermutlich nur so magisch vor, weil dieser Einsatz von `iter()`, bei dem nämlich eine Funktion aufgerufen wird, nicht so geläufig ist. Wenn man sich erstmal daran gewöhnt hat, kann eine `iter()`-Lösung viele `while True: [...] break`-Konstrukte ersetzen, was letztlich schöner aussieht.
Re: UTF-8 hexadezimal -> Zeichen
Verfasst: Samstag 31. Juli 2010, 09:43
von BlackJack
@snafu: Ich glaube Du verwechselst da etwas. So wird `iter()` hier nicht eingesetzt. Was ms4py zu magisch findet, ist, dass in einem `zip()` zweimal der selbe Iterator benutzt wird um Paare zu erzeugen.
Re: UTF-8 hexadezimal -> Zeichen
Verfasst: Samstag 31. Juli 2010, 10:01
von snafu
Stimmt, es wird ja lediglich das *Ergebnis* einer Funktion verwendet.
