string manipulation

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

Moin,

sorry das ich schon wieder hilfe brauche, aber bin leider noch recht unerfahren...

Folgendes Problem:

Code: Alles auswählen

find_artnr = re.compile(r"\d{5}-\d{3}")
artnr_match = find_artnr.findall(str(rawdata))

file = open(filepath,"w")
file.writelines(artnr_match)
file.close()
Eine Website wird nach Artikelnummern durchsucht diese kommen in den string und dieser wird auf die platte geschrieben,
das problem an der sache ist nur das da keine leerzeichen oder irgendwas anderes dazwischen ist.
Somit ist das ganze ziemlich unleserlich und sehr schlecht weiterzuverarbeiten.

Das ganze sieht in etwa so aus:
  • 13926-00115949-00016302-00016303-00016331-00116431-00016456-00016603-00016611-0001
    usw.
Da leider keine Leerzeichen oder sonstiges drin sind wo man ansetzen könnte hab ich keinen Plan wie ich da irgendwie kommas oder ähnliches zwischen die einzelnen Nummern bekomme.
Ein Nummerblock sieht wie folgt aus : 13926-001

Kann man jemand helfen das ganze durch kommas oder leerzeichen oder beides zu trennen?
BlackJack

@taake: An der Stelle solltest Du vielleicht einen Schritt vom zu lösenden Problem zurück treten und das Tutorial in der Dokumentation durcharbeiten. Da lernst Du dann was für Operationen es zum Beispiel auf Zeichenketten gibt. Oder was eine ``for``-Schleife ist.
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

Danke erstmal für die Antwort, ich hatte allerdings gehofft das man das ganze ohne Schleifen lösen kann.
So nach dem Motto füg alle 9 Zeichen ein Komma, Leerzeichen ein.
Oder das es möglich ist beim rc.compile das < am Ende jeder ArtNr. mit einzubeziehen und dann nach diesem zu suchen und zu ersetzen.
BlackJack

@taake: Wieso willst Du das ohne Schleife lösen? Das geht letztendlich nicht. Du kannst es mit der entsprechenden Zeichenkettenoperation ohne explizite Schleife hinschreiben, aber letztendlich wird von der Methode dann intern doch eine Schleife ausgeführt.
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

Ich weiß nicht ich hab damals in bash alles mit schleifen gelöst und will mal versuchen das ganze ohne hinzubekommen. (wie Python das im Hintergrund löst, ist mir im Moment noch relativ egal, da ich noch nicht so weit fortgeschritten bin mich damit zu beschäftigen)

Hab jetzt auch nen neuen Lösungsansatz der ohne Schleifen auskommt.

Und zwar

Code: Alles auswählen

find_artnr = re.compile(r"\d{5}-\d{3}\D{1}")
Dadurch habe ich das Zeichen welches hinter jeder ArtNr. steht mit dazu genommen, in diesem Fall ist es ein <

Jetzt müsste ich das ganze mit

artnr_match = str.replace()

durch ein komma leerzeichen ersetzen können, oder irre ich da?

Allerdings hab ich echt Probleme den syntax auf die Reihe zu bekommen.

Code: Alles auswählen

artnr_match = str.replace("\<,\,\ ")
meint immer
TypeError: replace() takes at least 2 arguments (0 given)

Weiß jemand wie man das '<' durch ein 'komma+leerzeichen' ersetzen kann.
hal42
User
Beiträge: 6
Registriert: Dienstag 5. Oktober 2010, 09:22

Ich versteh auch nicht was Du gegen Schleifen hast, ich finde die super ;)

Code: Alles auswählen

>>> t = "3535<3543<46347<678468<4364"
>>> t.replace("<", ", ")
'3535, 3543, 46347, 678468, 4364'
BlackJack

@taake: Arbeite das Tutorial durch, da lernst Du auch wie man Funktionen mit Argumenten aufruft.

Edit: Und Du irrst bei dem `replace()` denn das ist eine Funktion auf Zeichenketten -- das Ergebnis von `re.findall()` ist aber keine Zeichenkette.
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

@BlackJack:
Hoffe du nimmst es mir nicht übel, aber von den meisten Tut's bringen mich nicht wirklich weiter, ich gehöre zu den Leuten die es eigentlich nur via learning by doing lernen, wenn ich mir das tut anschaue, tipp ich es nach les es mir durch und am nächsten tag hab ich schon die hälfte wieder vergessen, nur wenn ich mir die ganzen infos selbst zusammensuche und anpasse lerne ich es wirklich.
Und die basics habe ich schon von bash.

Also wenn ich das nicht völlig falsch verstehe dann ist es schon ein string

Code: Alles auswählen

passman = urllib.request.HTTPPasswordMgrWithDefaultRealm()
passman.add_password( None, shopurl, username, password )

authhandler = urllib.request.HTTPBasicAuthHandler( passman )
opener = urllib.request.build_opener( authhandler )
urllib.request.install_opener( opener )


rawdata =(urllib.request.urlopen( 'http://*********/index.php?Sprachzeile=de&navigat=navia&action=missingpics&subject=').read())

#print(rawdata)
find_artnr = re.compile(r"\d{5}-\d{3}\D{1}")
artnr_match = find_artnr.findall(str(rawdata))

artnr_match = str.replace("<", ", ")

#print(artnr_match)

file = open(filepath,"w")
file.writelines(artnr_match)
file.close()
Soweit ich das sehe ist rawdata byecode wird dann aber durch "artnr_match = find_artnr.findall(str(rawdata))"
zu einem string.
Wenn ich das ganze nicht mache gehts nämlich nicht.
artnr_match = find_artnr.findall(rawdata)
TypeError: can't use a string pattern on a bytes-like object

von daher erscheint es mir irgendwie unlogisch das artnr_match kein string sein soll.

Aber gut ich bin kein experte und lasse mich auch gern belehren.


@hal42
Irgendwie klappt das nicht...

artnr_match = str.replace("<", ", ")
TypeError: replace() takes at least 2 arguments (1 given)
hal42
User
Beiträge: 6
Registriert: Dienstag 5. Oktober 2010, 09:22

Code: Alles auswählen

>>> artnr_match = "Irgendein String <34324<76987<987<7<897"
>>> artnr_match = artnr_match.replace("<", ", ")
>>> print artnr_match
Irgendein String , 34324, 76987, 987, 7, 897
Wo nimmst Du das str. her?
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

hal42 hat geschrieben:Wo nimmst Du das str. her?
Passt doch:

Code: Alles auswählen

>>> artnr_match = "Irgendein String <34324<76987<987<7<897"
>>> print str.replace(artnr_match,"<", ", ")
Irgendein String , 34324, 76987, 987, 7, 897
Und nein bitte so nicht verwenden.
Zur Erklaerung: `str` ist die String-Klasse und `str.replace` laesst sich als ungebundene Methode so nutzen, indem man als erstes Argument das `str`-Exemplar uebergibt. Bei ungebundenen Methoden wird eben nicht das erste Argument implizit uebergeben.
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

Ist mir auch gerade aufgefallen, hatte es aus der python doku auf der python hp.
Aber sehr gut, dadurch ist mir gerade einiges etwas klarer geworden, also danke für die Nachfrage.

Demnach müsste ich aus
find_artnr = re.compile(r"\d{5}-\d{3}\D{1}")
auch ein
find_artnr = find_artnr.compile(r"\d{5}-\d{3}\D{1}")
machen, richtig ?


Ich stelle allerdings gerade fest das BlackJack recht hatte, das ganze ist kein string sondern eine liste

damn

Daher funktioniert der replace auch nicht.


Edit:


Irgendwie muss es doch möglich sein aus ner liste wieder ein string zu machen, ich les mir auch gern entsprechende tut's durch, da es jetzt etwas bringen würde, allerdings laufen alle suchen via google ins leere ... :(
Benutzeravatar
hendrikS
User
Beiträge: 420
Registriert: Mittwoch 24. Dezember 2008, 22:44
Wohnort: Leipzig

Wenn klar ist das eine Artikelnummer immer 9 Zeichen lang ist (was offenbar aber nicht der Fall ist, denn Deine Zeichenkette ist 82 Zeichen lang) würde ich es durchslicen.

s[0:9]
s[9:18]
usw.

Und natürlich in einer Schleife. Genau len(s)/9 mal. Die Slicerei ist in Python ziemlich gut umgesetzt, wie ich letztens festgestellt habe.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

taake hat geschrieben:Irgendwie muss es doch möglich sein aus ner liste wieder ein string zu machen, ich les mir auch gern entsprechende tut's durch, da es jetzt etwas bringen würde, allerdings laufen alle suchen via google ins leere ... :(
Und wieder einmal: String-Methoden.

Code: Alles auswählen

>>> articles = ["foo", "bar", "baz"]
>>> "\n".join(articles)
'foo\nbar\nbaz'
>>> print "\n".join(articles)
foo
bar
baz
Wenn du die Artikel davor behandeln musst, solltest du dir `map` anschauen.
BlackJack

@taake: cofi hat Dir die passende Methode ja nun gezeigt aber genau diese *grundlegenden* Sachen stehen im Tutorial in der Python-Dokumentation. Man sollte die Grunddatentypen und die gängigsten Operationen halt schon drauf haben bevor man echte Probleme löst. Wie willst Du sonst wissen mit welchen Werkzeugen Du Deine Probleme angehen sollst, wenn Du die grundlegensten Dinge nicht kennst? Und Vorkenntnisse in Bash nützen da nichts, denn die kennt ja eigentlich gar keine Datentypen ausser Zeichenketten und "Arrays" die im Grunde auch nur Zeichenketten sind. Als Programmiersprache ist "Shell" ein schlechter Witz.

Das Argument mit dem vergessen zählt IMHO auch nicht. Wenn Du *jetzt* das Tutorial durcharbeitest (nicht nur lesen!) dann wirst Du die Sachen kennenlernen die Du für die Lösung Deines Problems brauchst. Wenn beim Durcharbeiten des Tutorials wirklich nichts hängen bleibt, solltest Du die Finger vom Programmieren lassen.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

taake hat geschrieben:... ich gehöre zu den Leuten die es eigentlich nur via learning by doing lernen, wenn ich mir das tut anschaue, tipp ich es nach les es mir durch und am nächsten tag hab ich schon die hälfte wieder vergessen, ...
Das geht mir eigentlich genauso. Vieles von dem, was man anfangs liest, scheint erstmal wieder verloren zu gehen. Aber unser Gehirn verliert nix. Umso mehr ich mit Python arbeite, umso mehr komme ich zwangsläufig mit Dingen in Berührung, die zum "scheinbar verloren gegangenen" gehören. Und plötzlich kommt mir dann dieses "das hab' ich schon mal irgendwo...".
Ich würde Dir ebenfalls sehr empfehlen, das offizielle Tutorial auszudrucken und durchzuarbeiten. Ein oft unterschätzer Effekt dabei ist auch, dass man damit lernt, mit der Python Reference umzugehen. Und ohne die geht nix.
Gerade hier im Forum bekommst Du meist nur Hinweise darauf, wie ein Problem gelöst werden könnte, was imho weit hilfreicher ist, als fertigen Code hingeknallt zu bekommen. Wenn Du Dich dann in der Documentation nicht zurechtfindest, kommst Du nicht weiter. Spätestens da endet "learning by doing".

Meine Meinung.

Gruß
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

Danke, das hat geklappt.

@BlackJack:

Du hast recht, ich werde das Tut mal durcharbeiten.
Hoffe das ich dennoch hier weiterhin willkommen bin fall ich noch irgendwelche Verständnissprobleme haben sollte.
Antworten