Hallo,
ich habe mal wieder ein Problem und bin zu blind, Pythons build-in Lösung zu finden.
gegeben: ein String mit line-feed, tabs, etc.
gesucht: derselbe String, wobei die Sonderzeichen einmal gefluchtet wurden
Beispiel:
vorher -> "Hello\tWorld" mit \t = 1 Tab-Zeichen
nachher -> "Hello\\tWorld", wobei aus Tab ein gefluchteter Backslash und ein t wurden
Wie aus dem Beispiel zu erkennen, müssen backslashs ebenfalls gefluchtet werden.
Ich habe mir eine Lösung selbst programmiert, aber ich wüsste gern eine Python-Funktion, die das für mich übernimmt. So wie escape_string() von MySQLdb. Aber da es diese Methode gibt, gehe ich mal davon aus, dass Python sowas nicht in den Bordmitteln hat, oder?
Kann mir jemand helfen?
Vielen Dank, Gruß
Michel
Strings fluchten
- Michael Schneider
- User
- Beiträge: 569
- Registriert: Samstag 8. April 2006, 12:31
- Wohnort: Brandenburg
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Das erste mal, dass ich das wort "gefluchtet" höre
Für python kannst du strings mit "repr" escapen:
Die Frage ist, nach welcher Logik? Wer soll den String danach einlesen? "\x00" mag ein gültiger String in python sein, in mysql vmtl nicht.gegeben: ein String mit line-feed, tabs, etc.
gesucht: derselbe String, wobei die Sonderzeichen einmal gefluchtet wurden
Für python kannst du strings mit "repr" escapen:
Code: Alles auswählen
x = "\x00"
esaped = repr(x)
assert len(escaped) == 6
assert escaped[1] == '\'
- Michael Schneider
- User
- Beiträge: 569
- Registriert: Samstag 8. April 2006, 12:31
- Wohnort: Brandenburg
Wirklich? Ich habe das schon oft gelesen.keppla hat geschrieben:Das erste mal, dass ich das wort "gefluchtet" höre
Stimmt. Also es soll für Python gefluchtet sein. Das heißt, dass definitiv kein lf oder tab oder cr im String mehr vorkommt, sondern durch die 'echten' Zeichen ersetzt wird, die man auch auf dem Bildschirm lesen kann. (Ausnahme ist der Backslash)keppla hat geschrieben: Die Frage ist, nach welcher Logik? Wer soll den String danach einlesen? "\x00" mag ein gültiger String in python sein, in mysql vmtl nicht.
Ich möchte die Daten vornehmlich übers Netz schicken und lf als terminator verwenden. Der String "\x00" würde ja als ein Zeichen (lf) im hexadezimalformat interpretiert werden, was letztlich dieselbe Wirkung hat.
kopfschüttelkeppla hat geschrieben:Für python kannst du strings mit "repr" escapen:
Man, das ist so einfach und doch so genial!
Aber: wie bekomme ich daraus wieder sicher den Originalstring? Ich meine, wenn ich eval verwende, dann kann dabei ja auch alles andere passieren. Gibt es eine Möglichkeit, den repr-String wieder direkt in den Originalstring umzuwandeln?
Vielen Dank!
Gruß,
Michel
Diese Nachricht zersört sich in 5 Sekunden selbst ...
-
- User
- Beiträge: 773
- Registriert: Mittwoch 5. November 2003, 18:06
- Wohnort: Schweiz
- Kontaktdaten:
Hi
Wäre es nicht einfacher bei der Übertragung übers Netzwerk zuerst die Grösse und dann die Daten zu übertragen?
<4byte Grösse><daten>
Dann weiss der Empfänger wieviele Daten er empfangen muss und braucht nicht auf einen Terminator zu warten, somit musst du auch nichts escapen.
Gruss
PS: Das Wort fluchten war mir bis jetzt auch unbekannt
*edit* Aber irgendwie passt das auch nicht, bei dict.leo.org gibt fluchten ja aligning und bei Wiki steht 'etwas in eine (gerade) Linie bringen', '(sich) ausrichten'. Den String musst du ja nicht ausrichten oder?
Wäre es nicht einfacher bei der Übertragung übers Netzwerk zuerst die Grösse und dann die Daten zu übertragen?
<4byte Grösse><daten>
Dann weiss der Empfänger wieviele Daten er empfangen muss und braucht nicht auf einen Terminator zu warten, somit musst du auch nichts escapen.
Gruss
PS: Das Wort fluchten war mir bis jetzt auch unbekannt
*edit* Aber irgendwie passt das auch nicht, bei dict.leo.org gibt fluchten ja aligning und bei Wiki steht 'etwas in eine (gerade) Linie bringen', '(sich) ausrichten'. Den String musst du ja nicht ausrichten oder?
- Rebecca
- User
- Beiträge: 1662
- Registriert: Freitag 3. Februar 2006, 12:28
- Wohnort: DN, Heimat: HB
- Kontaktdaten:
http://www.python-forum.de/topic-13229.html
Edit: Ich hab bei fluchten auch an ausrichten (im Sinne von align) gedacht.
Edit: Ich hab bei fluchten auch an ausrichten (im Sinne von align) gedacht.
Offizielles Python-Tutorial (Deutsche Version)
Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
- Michael Schneider
- User
- Beiträge: 569
- Registriert: Samstag 8. April 2006, 12:31
- Wohnort: Brandenburg
Hi Rayo,rayo hat geschrieben:Hi
Wäre es nicht einfacher bei der Übertragung übers Netzwerk zuerst die Grösse und dann die Daten zu übertragen?
<4byte Grösse><daten>
es gibt generell zwei Möglichkeiten der Übertragung. Wenn die Größe bekannt ist, dann ist es zweckmäßig die Größe anzugeben und dann n Zeichen zu lesen. Insbesondere in Hinblick auf eine Fortschrittsauswertung.
Es gibt aber auch Umstände, da möchte man einen Stream lesen, der jederzeit unterbrochen werden kann. Beispiel: eine x Mb Datei, die, solange sich kein wichtigeres Paket dazwischendrängt (z.B. eine Chatzeile), gleichmäßig übertragen werden kann. Würde man die in Häppchen zerteilen, hätte man entweder Verzögerungen bei der Übertragung der wichtigen Pakete (große Chunks) oder mehr Overhead und Verarbeitungsaufwand (kleine Chunks).
Ich wollte auch eigentlich kein direktes Beispiel angeben, damit die Diskussion nicht von der eigentlichen Frage abdriftet, denn es geht um das generelle Problem. (ich möchte auch binäre Strings pickeln (mit einem alten Pickle-modul), wobei ich nur die Sonderzeichen fluchten will)rayo hat geschrieben:Dann weiss der Empfänger wieviele Daten er empfangen muss und braucht nicht auf einen Terminator zu warten, somit musst du auch nichts escapen.
Gruß,
Michel
p.s. Ich kann mich mit dem neudeutschen "escapen" nicht wirklich anfreunden.
Diese Nachricht zersört sich in 5 Sekunden selbst ...
- Michael Schneider
- User
- Beiträge: 569
- Registriert: Samstag 8. April 2006, 12:31
- Wohnort: Brandenburg
Hi Rebecca,Rebecca hat geschrieben:http://www.python-forum.de/topic-13229.html
Edit: Ich hab bei fluchten auch an ausrichten (im Sinne von align) gedacht.
ich habe auch schon an encode/decode gedacht, aber ich habe keinen Codec namens "string-escape". Dafür bekomme ich einen
Kann ich den irgendwo herbekommen?ExceptHook hat geschrieben:LookupError: unknown encoding: string-escape
Gruß,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
würde sich da nicht sowas wie base64 anbieten? Hat mit absoluter Sicherheit nur einen wohldefinierten Zeichensatz.Ich möchte die Daten vornehmlich übers Netz schicken und lf als terminator verwenden.
Code: Alles auswählen
"Hail Eris!\nAll Hail Discordia!".encode("base64")
Ich fand längenpräfixe eigentlich immer eine recht angenehme lösung, wenn man beliebig lange elemente haben möchte, macht man es halt wie http-chunked: man liest solange chunks ein, bis ein leeres kommt.
- Michael Schneider
- User
- Beiträge: 569
- Registriert: Samstag 8. April 2006, 12:31
- Wohnort: Brandenburg
Um nochmal auf base64 einzugehen: das macht aus 3 Zeichen 4, was den Text um 25% verlängert, während eine hand voll Sonderzeichen vielleicht 4-5% ausmacht. Außerdem hatte ich damit Probleme mit Umlauten wie ä, ö, ü, weil der base64-codec immer über das ascii-Format lief, welches bestimmt chars (>= Wert 128) nicht übersetzen konnte. Darum hatte ich den base64-Ansatz zurückgestellt.keppla hat geschrieben:würde sich da nicht sowas wie base64 anbieten? Hat mit absoluter Sicherheit nur einen wohldefinierten Zeichensatz.Ich möchte die Daten vornehmlich übers Netz schicken und lf als terminator verwenden.
Ich möchte wirklich nicht unhöflich klingen. Aber es geht hier nicht um alternative Netzwerkprotokolle, sondern um die Frage wie man vorhandene Strings per Funktion fluchten/escapen und das Ergebnis wieder in den Originalstring umwandeln kann (siehe Originalmail). Wie gesagt betrachte ich das als Grundsatzproblem und suche keine gute Möglichkeit, das Fluchten zu umgehen. Das sollte jetzt nicht undankbar wirken!keppla hat geschrieben: Wenn du dir ein Netzwerkprotokoll ausdenkst, hängt es imho sehr davon ab, was du erreichen möchtest.
Ich fand längenpräfixe eigentlich immer eine recht angenehme lösung, ...
Übrigens heißt der Backslash auf deutsch doch Fluchtungszeichen. Warum dann die Aktion nicht fluchten?
Grüße,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
ist schon klar, allerdings ist es wohl ebenfalls nicht unhöflich, zu versuchen zu ermitteln, ob das vorgetragene Problem das eigentliche Problem ist.Ich möchte wirklich nicht unhöflich klingen. Aber es geht hier nicht um alternative Netzwerkprotokolle, sondern um die Frage wie man vorhandene Strings per Funktion fluchten/escapen und das Ergebnis wieder in den Originalstring umwandeln kann (siehe Originalmail).
Sagte ich ja nicht, ich sagte nur, dass ich diese (eindeutschung?) heute das erste mal höre.Übrigens heißt der Backslash auf deutsch doch Fluchtungszeichen. Warum dann die Aktion nicht fluchten?
Ich habe gerade mal in der doku nachgelesen, string_escape bzw unicode_escape scheinen das zu sein, was du suchst.
Stellt sich die Frage, was für Stilblüten da bei "callback function" oder "message handler" rauskommenY0Gi hat geschrieben:Wird da etwa "to escape" mit "fluchten" übersetzt? Holla ...
Michael, ich hoffe, du liest nicht mehr dort, wo du das zuerst gelesen hast
- Rebecca
- User
- Beiträge: 1662
- Registriert: Freitag 3. Februar 2006, 12:28
- Wohnort: DN, Heimat: HB
- Kontaktdaten:
Wikipedia, Leo und ich kennen den Backslash im Deutschen als umgekehrten Schrägstrich oder linksseitigen Schrägstrich.
Soweit ich weiss, gehoert der string-escape-Codec standardmaessig dazu, ich hab ihn unter Debian jedenfalls hier:
Soweit ich weiss, gehoert der string-escape-Codec standardmaessig dazu, ich hab ihn unter Debian jedenfalls hier:
python2.4-minimal: usr/lib/python2.4/encodings/string_escape.py
python2.5-minimal: usr/lib/python2.5/encodings/string_escape.py
Offizielles Python-Tutorial (Deutsche Version)
Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
- Michael Schneider
- User
- Beiträge: 569
- Registriert: Samstag 8. April 2006, 12:31
- Wohnort: Brandenburg
Unter Python2.2 habe ich nur:
re: Fluchten
Ok, ich gebe mich geschlagen - schaut doch mal bei Google unter dem Begriff
Danke für eure Hilfe!!
Gruß,
Michel
Damit wird das Ergebnis zwar beim Dekodieren in einen Unicode-String umgewandelt, aber mit str bekomme ich das Original wieder.raw_unicode_escape.py
unicode_escape.py
re: Fluchten
Ok, ich gebe mich geschlagen - schaut doch mal bei Google unter dem Begriff
... ich bin Trendsetter - nur hoffentlich greift das keiner auf."strings fluchten"
Danke für eure Hilfe!!
Gruß,
Michel
Diese Nachricht zersört sich in 5 Sekunden selbst ...
musst das ganze auch decodieren:Michael Schneider hat geschrieben:Unter Python2.2 habe ich nur:Damit wird das Ergebnis zwar beim Dekodieren in einen Unicode-String umgewandelt, aber mit str bekomme ich das Original wieder.raw_unicode_escape.py
unicode_escape.py
Code: Alles auswählen
x = "Hail Eris!\nAll Hail Discordia!"
assert x == x.encode("string_escape").decode("string_escape")
- Michael Schneider
- User
- Beiträge: 569
- Registriert: Samstag 8. April 2006, 12:31
- Wohnort: Brandenburg
Hi Keppla,keppla hat geschrieben:musst das ganze auch decodieren:Michael Schneider hat geschrieben:Unter Python2.2 habe ich nur:Damit wird das Ergebnis zwar beim Dekodieren in einen Unicode-String umgewandelt, aber mit str bekomme ich das Original wieder.raw_unicode_escape.py
unicode_escape.py
Code: Alles auswählen
x = "Hail Eris!\nAll Hail Discordia!" assert x == x.encode("string_escape").decode("string_escape")
was meinst Du damit?
Erstens habe ich kein "string_escape" codec (habe bei dem obigen Suchergebnis nach allen Dateien gesucht, die "escape" enthalten).
Zweitens bringt es mir nichts, den String zu codieren und gleich wieder zu dekodieren. Ich muss ihn doch zwischendurch noch senden/bearbeiten/speihern, oder? Ich habe Dich bestimmt falsch verstanden.
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Sorry, vergiss mein Post, ich hatte das "Python 2.2" völlig übersehen, und dich irgendwie ganz anders verstanden. Bin scheinbar nicht gerade auf der höhe.
Also, mal etwas produktiver:
mit codec.register kann man sich "eigene" codecs registrieren. Eine mögliche lösung wäre, wenn der "string_encode" in python geschrieben ist, diesen teil aus python2.5 zu kopieren (unter Beachtung der Lizenz versteht sich), ihn zu registrieren, und mitzuverteilen.
Hatte ich übersehen.Erstens habe ich kein "string_escape" codec (habe bei dem obigen Suchergebnis nach allen Dateien gesucht, die "escape" enthalten).
Damit wollte ich die symmetrie der zwei funktionen verdeutlichen, in der Fehlannahme, dass du das mit irgendwelchen scripts lösen wolltest. Wie gesagt, is heut nicht mein tag.Zweitens bringt es mir nichts, den String zu codieren und gleich wieder zu dekodieren.
Also, mal etwas produktiver:
mit codec.register kann man sich "eigene" codecs registrieren. Eine mögliche lösung wäre, wenn der "string_encode" in python geschrieben ist, diesen teil aus python2.5 zu kopieren (unter Beachtung der Lizenz versteht sich), ihn zu registrieren, und mitzuverteilen.
- Michael Schneider
- User
- Beiträge: 569
- Registriert: Samstag 8. April 2006, 12:31
- Wohnort: Brandenburg
Hi Keppla,keppla hat geschrieben: Also, mal etwas produktiver:
mit codec.register kann man sich "eigene" codecs registrieren. Eine mögliche lösung wäre, wenn der "string_encode" in python geschrieben ist, diesen teil aus python2.5 zu kopieren (unter Beachtung der Lizenz versteht sich), ihn zu registrieren, und mitzuverteilen.
daran habe ich auch schon gedacht und wollte fragen, ob mir jemand dieses string-codec Modul posten kann. Aber wie es aussieht, sind die wrapper.py Dateien mit "escape" im Namen (oben) nur Wrapper für C-Funktionen. Daher denke ich, dass das auch für den string_escape codec gilt.
Aber mit dem unicode_escape fahre ich ja ganz gut, das ist vielleicht sogar noch etwas sicherer, was Umlaute betrifft.
Gruß,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Wenn ich dein vorhaben richtig verstehe, dürften die doch keine probleme machen können.Michael Schneider hat geschrieben:Aber mit dem unicode_escape fahre ich ja ganz gut, das ist vielleicht sogar noch etwas sicherer, was Umlaute betrifft.
Ob umlaute richtig verstanden werden ist ja eher eine frage, ob sender und empfänger sich auf ein encoding geeinigt haben (was bei dir ja zwangsläufig ist, da du beide Programmierst).
Wenn ich dein Protokoll richtig verstehe, möchtest du "token" senden, trennzeichen wäre \n.
Womit klar wäre: \n ist dein einziges steuerzeichen, du musst also nur dieses escapen.
So einen codec selbst zu schreiben ist imho nicht so schwer.
edit: um mal meinen Worten taten folgen zu lassen:
Code: Alles auswählen
def decode(s, escape, trans):
chunks = []
left = 0
while True:
right = s.find(escape, left)
if right == -1:
chunks.append(s[left:])
break
else:
chunk = s[left:right] + trans[s[right + 1]]
chunks.append(chunk)
left = right + 2
return ''.join(chunks)
message = r"Hail Eris!\nAll Hail Discordia!\n\\ <- this is a backslash"
print message
print decode(message, '\\', {'n' : '\n', '\\' : '\\'})
- Michael Schneider
- User
- Beiträge: 569
- Registriert: Samstag 8. April 2006, 12:31
- Wohnort: Brandenburg
Hi,keppla hat geschrieben:So einen codec selbst zu schreiben ist imho nicht so schwer.
wie ich eingangs schrieb, habe ich das auch selbst schon implementiert. Aber dabei kam ich auf meine grundsätzliche escape/unescape Frage.
Schönes Wochenende,
Michel
Diese Nachricht zersört sich in 5 Sekunden selbst ...