Hallo Leute,
nicht nur hier bin ich neu, auch was Python angeht. Daher stehe vor einem Problem, dass jeden Fortgeschrittenen wahrscheinlich den Kopf schütteln lässt:
Gegeben ist der Eintrag aus einem Mehrzeilen-Feld in einem HTML-Formular.
Dieser enthält unter anderem Zeilenschaltungen.
Das mag aber das Modul FlatDB, mit dessen Hilfe die Daten gespeichert werden sollen, garnicht. (Jedenfalls knallt es beim Wieder-Auslesen.)
Nun ist der Feldinhalt, wenn ich ihn aus cgi.userinput heraushole im Format string.
Also, als alter Pascal-Programmierer: String auf Zeichen kleiner SPACE gescannt und alle solchen durch Leerzeichen ersetzt
Nun ist aber der Typ string bei Python nicht veränderbar.
Also schwupps in eine Liste konvertiert, diese bearbeitet und zurück in einen string konvertiert. Etwas umständlich und -- jetzt kommts -- das Ergebnis ist unbrauchbar. Aus "123" wird ['1','2','3'] und das ist nicht so ganz das, was ich mir vorstelle.
Ich suche also einen Weg
- entweder doch an Strings zu manipulieren oder
- aus einer Liste einen brauchbaren String zu machen.
Wer weiß Rat?
Strings "bearbeiten" mit Python
-
- User
- Beiträge: 1
- Registriert: Sonntag 8. September 2002, 21:56
- Wohnort: Langenhagen
Wie Du richtig erkannt hast, sind Strings in sich nicht veränderbar. Aber mußt Du wirklich genau diesen String verändern? Wenn nein, mache es doch so:man-draker hat geschrieben: ...
Ich suche also einen Weg
- entweder doch an Strings zu manipulieren oder
- aus einer Liste einen brauchbaren String zu machen.
Wer weiß Rat?
Code: Alles auswählen
>>> x = 'Hallo\nDu da!'
>>> print x
Hallo
Du da!
>>> x = x.replace('\n', ' ')
>>> print x
Hallo Du da!
Und zum Problem Liste->String:
Code: Alles auswählen
>>> l = ['L', 'i', 's', 't', 'e']
>>> import string
>>> print string.join(l)
L i s t e
>>> print string.join(l, '')
Liste
>>> print string.join(l, '-')
L-i-s-t-e
-
- User
- Beiträge: 69
- Registriert: Donnerstag 29. August 2002, 17:10
- Wohnort: Erfurt
- Kontaktdaten:
Aus meinem Alpha-Status Gästebuch:
(meinst doch ne <textarea>!?)
d.h.: substituiere (ersetze) alle "\r\n" (hab mir mal den Dictionary puffer voll anzeigen lassen und da sind das halt die Enter, nich nur die "\n") durch "<br>" und zwar beim Inhalt von kommentar.
(meinst doch ne <textarea>!?)
Code: Alles auswählen
import re, cgi
puffer = cgi.FieldStorage()
kommentar = puffer["kommentar"].value
kommentar = re.sub("\r\n", "<br>", kommentar)
-
- Gründer
- Beiträge: 410
- Registriert: Dienstag 30. Juli 2002, 18:03
- Wohnort: Oestrich-Winkel
- Kontaktdaten:
\r\n setzen, soweit ich weiss, nur Browser die auf Windows laufen. Wenn du Netscape o.ä. unter Linux benutzt, so hast du nur ein \r (oder war es nur \n? ) Also besser ist beides einzeln, bei Bedarf zu ersetzen.
irc: #python.de @ irc.freenode.net | [url=http://pythonwiki.pocoo.org]python-wiki[/url] | [url=http://www.pythonwiki.de/PythonDeForum/Faq]python-forum FAQ[/url]
Zuerst einmal Dank an alle Hilfesteller.
1. Dass die Liste als String so seltsam aussah lag im Zweifel an meinem falschen Verstehen der Funktion str(), die halt keine liste -> string Funktion ist.
2. Die Antwort von joerg ist die exakt auf die gestellte Frage passende.
3. Die Antwort von RicmanX ist die, die das konkrete Problem am elegantesten (aus Sicht des Kodierenden) löst. Diese habe ich vorerst umgesetzt (und sie funktioniert).
4. Wenn die Benutzer es schaffen weitere unverdauliche Zeichen in die Eingabe zu packen, komme ich eventuell auf Methode Eins zurück, denn:
5. Weil zumindest der Konqueror (zu meiner Überraschung) einen Druck auf die Enter-Taste mit dem Einfügen von x0d x0a (oder \r\n) beantwortet, es andere Browseraber durchaus anders machen könnten (\n bei UNIX und ich fürchte \r beim Mac) suche ich jetzt zuerst einmal nach \r\n und anschließend sicherheitshalber noch einmal nach \n.
Hier das Ergebnis:
Ihr habt mir jedenfalls um die Klippe, an der ich hängen geblieben bin, herum geholfen. Dafür vielen Dank.
1. Dass die Liste als String so seltsam aussah lag im Zweifel an meinem falschen Verstehen der Funktion str(), die halt keine liste -> string Funktion ist.
2. Die Antwort von joerg ist die exakt auf die gestellte Frage passende.
3. Die Antwort von RicmanX ist die, die das konkrete Problem am elegantesten (aus Sicht des Kodierenden) löst. Diese habe ich vorerst umgesetzt (und sie funktioniert).
4. Wenn die Benutzer es schaffen weitere unverdauliche Zeichen in die Eingabe zu packen, komme ich eventuell auf Methode Eins zurück, denn:
5. Weil zumindest der Konqueror (zu meiner Überraschung) einen Druck auf die Enter-Taste mit dem Einfügen von x0d x0a (oder \r\n) beantwortet, es andere Browseraber durchaus anders machen könnten (\n bei UNIX und ich fürchte \r beim Mac) suche ich jetzt zuerst einmal nach \r\n und anschließend sicherheitshalber noch einmal nach \n.
Hier das Ergebnis:
Code: Alles auswählen
def delEnter(such):
s = re.sub("\r\n", "<br>", such)
s = re.sub("\n", "<br>", s)
return s
-
- User
- Beiträge: 69
- Registriert: Donnerstag 29. August 2002, 17:10
- Wohnort: Erfurt
- Kontaktdaten:
Code: Alles auswählen
def delEnter(such):
return re.sub(os.linesep, "<br>", such)
Hallo!
Jan
Was bringt Dir das? Das Script unter Win ausgeführt ersetzt keine "\n" ohne "\r"' davor und unter Unix ausgeführt wird bei "\r\n" nur das "\n" ersetzt.RicmanX hat geschrieben:Code: Alles auswählen
def delEnter(such): return re.sub(os.linesep, "<br>", such)
Jan
Hallo Leute,
Ich persönlich finde re etwas übertrieben, um einzelne Zeichen oder klar definierte Zeichenketten zu suchen und zu ersetzen, da die String-Methoden das auch können, und zwar deutlich schneller. Bei mir liefert der folgende ganz einfache Test:
ungefähr einen Geschwindigkeitsvorteil vom Faktor 10 zugunsten der String-Methode!
Selbst wenn die Zeitmessung nicht so genau ist, und auf anderen Systemen vielleicht der Faktor nicht so hoch ist, sehe ich keinen Vorteil der re-Methoden, solange man reguläre Ausdrücke nicht wirklich braucht. Die Strings und ihre Methoden hat man immer, re muß man erst importieren.
Und bei der Ersetzungsmethode bin ich eher ein Fan der Trennung von Daten und Funktion, ich würde wahrscheinlich eine leicht erweiterbare Ersetzungstabelle und eine allgemeine Ersetzungsfunktion definieren, aber das ist wirklich Geschmackssache:
Ich persönlich finde re etwas übertrieben, um einzelne Zeichen oder klar definierte Zeichenketten zu suchen und zu ersetzen, da die String-Methoden das auch können, und zwar deutlich schneller. Bei mir liefert der folgende ganz einfache Test:
Code: Alles auswählen
import re, time
s = 'abcdefg' * 100
t = time.time()
for i in range(1000):
s = re.sub('a', 'X', s)
s = re.sub('X', 'a', s)
print time.time() - t
t = time.time()
for i in range(1000):
s = s.replace('a', 'X')
s = s.replace('X', 'a')
print time.time() - t
Selbst wenn die Zeitmessung nicht so genau ist, und auf anderen Systemen vielleicht der Faktor nicht so hoch ist, sehe ich keinen Vorteil der re-Methoden, solange man reguläre Ausdrücke nicht wirklich braucht. Die Strings und ihre Methoden hat man immer, re muß man erst importieren.
Und bei der Ersetzungsmethode bin ich eher ein Fan der Trennung von Daten und Funktion, ich würde wahrscheinlich eine leicht erweiterbare Ersetzungstabelle und eine allgemeine Ersetzungsfunktion definieren, aber das ist wirklich Geschmackssache:
Code: Alles auswählen
transTab = (('\r', ''),('\n', '<br>'),('bla', 'fasel'))
def translate(s, tab=transTab):
for old, new in tab:
s = s.replace(old, new)
return s
print translate('Dies \r\n ist \n ein Text')
Dies <br> ist <br> ein Text
-
- User
- Beiträge: 69
- Registriert: Donnerstag 29. August 2002, 17:10
- Wohnort: Erfurt
- Kontaktdaten:
Unix hat nur "\n", Windows hat "\r\n" usw.Voges hat geschrieben:Hallo!Was bringt Dir das? Das Script unter Win ausgeführt ersetzt keine "\n" ohne "\r"' davor und unter Unix ausgeführt wird bei "\r\n" nur das "\n" ersetzt.RicmanX hat geschrieben:Code: Alles auswählen
def delEnter(such): return re.sub(os.linesep, "<br>", such)
Jan
Und das os Modul fragt nach dem OS und setzt entsprechend den Richtigen LineSeparator.
Da eine <textarea> immer nur diese OS spezifischen Zeilenumbrüche verwendet und es hier um HTML geht, ist es ja das Ziel mit möglich wenigst Abfragen/Aktionen diesen Zeilenumbruch zu ersetzen. Und genau das macht diese Funktion: je nach OS (bzw. mit Browser) wird der Zeilenumbruch zu nem HTML Zeilenumbruch gewandelt. Wozu unbedingt etwas universelles, aber langsameres machen, womit das Script eh nie konfrontiert wird?
Hallo!
Jan
Ich verstehe es immer noch nicht. Es geht doch um ein CGI-Script, also ein Script, das auf dem Server läuft. Was hilft es Dir zu wissen, wie der Lineseperator des Server-OS lautet (bei Linux z.B. "\n"), wenn Dir der Client (sprich Browser) was anderes im Textarea-Text für Umbrüche vorsieht (bei Netscape/Win z.B. "\r\n"). Ein re.sub(os.linesep, "<br>", such) macht dann aus "bla\r\nblub" ein "bla\r<br>blub" (hab' ich getestet). Vielleicht reden wir aber auch von verschiedenen Sachen ;-)RicmanX hat geschrieben: Unix hat nur "\n", Windows hat "\r\n" usw.
Und das os Modul fragt nach dem OS und setzt entsprechend den Richtigen LineSeparator.
Jan
-
- User
- Beiträge: 728
- Registriert: Sonntag 22. September 2002, 08:32
- Wohnort: Sauerland
- Kontaktdaten:
Mal ne bescheidene Zwischenfrage, was passiert, wenn die Datei auf einen Server hochgeladen wird und das Script auf dem Server ausgeführt wird? Dann gibt es vier Möglichkeiten: WW, WU, UW, UU (1.Stelle OS Server, 2. Stelle OS Client). Dieses Script dürfte doch nur bei Kombination WW oder UU greifen.Voges hat geschrieben: Und das os Modul fragt nach dem OS und setzt entsprechend den Richtigen LineSeparator.
Gibts Alternativen? Unter Linux / Unix steht ja mit file ein entsprechendes Programm zur Verfügung. Bei Windows ist mir derartiges nicht bekannt.
Andererseits, ist es wichtig, dass ich hier nach OS unterscheide? Enternen wir doch erst mal Ballast (/r) und ersetzen dann /n. Sollte doch Sauber sein oder?
Hans
-
- User
- Beiträge: 728
- Registriert: Sonntag 22. September 2002, 08:32
- Wohnort: Sauerland
- Kontaktdaten:
Also ein /r ohne /n kenne ich nur von Druckdateien, nämlich bei Nadelprintern. hallo Welt/rhallo Welt sorgt dafür, dass der Wagen einmal nich links gefahren wird ohne dabei einen Zeilenvorschub zu machen und die Zeile dann nochmal zu Drucken. Das ganze erscheint dann FETT
Ich denke mal, das es in diesem Fall nicht um eine Druckdatei handelt. Und wenn die Datei nicht verändert werden darf, dann arbeite doch mit einer Kopie.
Wie war das eigentlich mit Macs, BeOS und co? /n oder /r/n ?
Hans
Ich denke mal, das es in diesem Fall nicht um eine Druckdatei handelt. Und wenn die Datei nicht verändert werden darf, dann arbeite doch mit einer Kopie.
Wie war das eigentlich mit Macs, BeOS und co? /n oder /r/n ?
Hans