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
UTF-8 hexadezimal -> Zeichen
Mit Python 2.6 (antike Versionen stehen mir nicht zur Verfügung) erhalte ich hiermit ein "ü":aurikeL hat geschrieben:[...], allerdings weiß ich nicht, wie ich das C3 BC zu einem "ü" umwandle
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)
Ja, das geht. Hab es etwas umständlich gelöst, vielleicht geht das noch besser:
(Unter 2.6 getestet)
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")
ü
„Lieber von den Richtigen kritisiert als von den Falschen gelobt werden.“
Gerhard Kocher
http://ms4py.org/
Gerhard Kocher
http://ms4py.org/
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
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.
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
Also unter 2.6 nicht, ist das mit 2.3 so?cofi hat geschrieben:im Allgemeinen sieht die `repr` Darstellung genau so aus, also wenn man z.b. Listen `print`et
Code: Alles auswählen
>>> [s.decode("utf8")]
[u'\xfc']
„Lieber von den Richtigen kritisiert als von den Falschen gelobt werden.“
Gerhard Kocher
http://ms4py.org/
Gerhard Kocher
http://ms4py.org/
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()
Danke für eure Antworten, ich werde sie am Montag testen.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.
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.
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()
„Lieber von den Richtigen kritisiert als von den Falschen gelobt werden.“
Gerhard Kocher
http://ms4py.org/
Gerhard Kocher
http://ms4py.org/
@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.BlackJack hat geschrieben:@ms4py: Etwas zu sehr vereinfacht, denn nicht alle UTF-8 Sequenzen sind nur zwei Bytes lang.
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?
„Lieber von den Richtigen kritisiert als von den Falschen gelobt werden.“
Gerhard Kocher
http://ms4py.org/
Gerhard Kocher
http://ms4py.org/
@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?)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.
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
Auslagern in eine Funktion wäre im Prinzip auch schon in Ordnung
„Lieber von den Richtigen kritisiert als von den Falschen gelobt werden.“
Gerhard Kocher
http://ms4py.org/
Gerhard Kocher
http://ms4py.org/
@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']
So geht's mit Python 3.x:
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
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'))
Code: Alles auswählen
lambda m:m.group(1).decode("hex").decode("utf-8")
@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.
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.
@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.