Anführungszeichen ersetzen

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
kidchino
User
Beiträge: 91
Registriert: Montag 17. November 2014, 14:18

Hey zusammen,

ist wahrscheinlich ein regex Problem aber ich komme nicht drauf und finde nix bei google und Konsorten.
Ich möchte in einem String die " entfernen. Leider klappt es nicht.

Code: Alles auswählen

spalte1 = row[1]
spalte1= spalte1.replace(Chr(34),"X")
print(spalte2, row[1]) #zum vergleich
Hatte auch schon

Code: Alles auswählen

spalte1= spalte1.replace("\p{Pi}","X")
spalte1= spalte1.replace("\"","X")
spalte1= spalte1.replace(""\"","X")
probiert. Aber es funzt nicht.

Jemand eine Idee?
LG
kid
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Wie kommst Du darauf, dass hier ein "regex Problem" besteht? Du fasst regex doch überhaupt nicht an? Interessant wäre natürlich, was sich hinter ``row[1]`` verbirgt. Zudem wäre es nützlich, wenn Du uns denselben Code zeigst, den Du letztlich auch verwendest, denn ...

Code: Alles auswählen

spalte1= spalte1.replace(Chr(34),"X")
... wird so nicht funktionieren.

Wie auch immer, bei mir funktioniert...

Code: Alles auswählen

>>> test = 'this (") is a double'
>>> test.replace('"', 'X')
'this (X) is a double'
>>> test.replace(chr(34), 'X')
'this (X) is a double'
>>> test.replace("\"", 'X')
'this (X) is a double'
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
kidchino
User
Beiträge: 91
Registriert: Montag 17. November 2014, 14:18

Hi,

das ist der Code den ich nutze:

Code: Alles auswählen

with open(os.path.join(pfad, dateiname), "rb") as f: #öffnet die jeweilige datei
        reader = csv.reader(f, delimiter="\t") #liest die zeilen aus, tabstop getrennt
        next(reader) #überspringt jeweils die erste zeile 
        
        for row in reader:   #schleife für jede zeile
            #if row[58] <> "": # prüft nur ob 58 nicht leer ist. die darf eigentlich nicht leer sein
             #  paperIdOhneWos = row[58].replace ("WOS:", "") #entfernt in Spalten 58 das WOS von der Paper-No und schreibt es in die Var. paperIdOhneWos
              # row.append(paperIdOhneWos) #hängt paperIdOhneWos hinten als Spalte dran
                #print (paperIdOhneWos)
            spalte1 = row[1]
            spalte1= spalte1.replace('\"','x')
            print(spalte1, row[1])
            liste.append(row) #schreibt die zeilen in die liste
Die Testdatei sieht so aus:

Code: Alles auswählen

PT	AU	BA
A1	"B1	C1
A2	B2	C2
A3	B3	C3
Eigentlich will ich aus der gesamten Datei alle (") löschen (nicht nur in row[1]), da die Anführungszeichen nachher beim Einlesen in MySQL Fehler verursachen. Es gibt in den Dateien viele Anführungszeichen, die nicht geschlossen werden. Das liegt wahrscheinlich daran, dass die Urdaten wohl per Hand eingescannt wurden und auch Quadrate (²) teilweise als (") gedeutet wurden.
Das ist dann der Output:

Code: Alles auswählen

A1	"B1	C1
A2	B2	C2
A3	B3	C3"
VG
Kid
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@kidchino: warum sollten " Fehler in einer Datenbank verursachen? Werden da irgendwelche Constraints überprüft?
Du mußt einfach für alle Spalten replace aufrufen:

Code: Alles auswählen

row = [cell.replace('"', 'x') for cell in row]
BlackJack

@kidchino: Also ich bekomme bei der Beispieldatei eine Ausnahme beim Versuch den zweiten Datensatz zu lesen. Und zwar schon in Python. Zu der angeblichen Ausgabedatei komme ich also gar nicht erst:

Code: Alles auswählen

In [3]: next(r)
Out[3]: ['PT', 'AU', 'BA']

In [4]: next(r)
---------------------------------------------------------------------------
Error                                     Traceback (most recent call last)
<ipython-input-4-0b5056469c9c> in <module>()
----> 1 next(r)

Error: newline inside string
kidchino
User
Beiträge: 91
Registriert: Montag 17. November 2014, 14:18

Hi
BlackJack hat geschrieben:Zu der angeblichen Ausgabedatei komme ich also gar nicht erst:
Mit Output meinte ich erstmal nur den Print(spalte1). Dort kommt ja

Code: Alles auswählen

('B1\tC1\r\nA2\tB2\tC2\r\nA3\tB3\tC3')
anstelle von

Code: Alles auswählen

('B1')
raus.
Es wird dann auch in der Ausgabe test.csv Datei ein " hinter C3 gesetzt.

Beim Einlesen der CSV Datei (nicht der Beispiel Datei) wurde dann Spalten vertauscht. Ich weiß nicht, ob das nicht geschlossene Anführungszeichen dafür verantwortlich ist, aber bei den falsch eingelesenen Dateien kam immer ein nicht geschlossenes Anführungszeichen vor.
VG
BlackJack

@kidchino: Nochmal: Soweit kommt das Programm bei mir gar nicht weil beim *einlesen* das schon bei dem Datensatz abbricht. Wie kann etwas ausgegeben werden was nicht gelesen werden konnte?

Das beim Schreiben von 'B1\tC1\r\nA2\tB2\tC2\r\nA3\tB3\tC3' das ganze in Anführungszeichen gesetzt wird ist klar weil in diesem Zellenwert sowohl der Trenner als auch das Zeilenende vorkommt.
kidchino
User
Beiträge: 91
Registriert: Montag 17. November 2014, 14:18

Hi BlackJack,

Wenn ich den Ansatz von Sirius folge:

Code: Alles auswählen

for row in reader:   #schleife für jede zeile
            row = [cell.replace('"', 'x') for cell in row]
            print (row)
            liste.append(row) #schreibt die zeilen in die liste
Dann habe ich diesen Output (ohne Fehler):

Code: Alles auswählen

A1	"B1	C1
A2	B2	C2
A3	B3	C3"
VG
BlackJack

@kidchino: Also ich wiederhole das jetzt noch einmal, wenn es dann nicht ankommt, weiss ich auch nicht wie ich mich da noch verständlicher ausdrücken soll: Bei mir bricht das beim *lesen* mit der weiter oben angegeben Ausnahme ab. Ich komme nie zu einer Ausgabedatei mit Deinem Code. Also entweder gibt da einen sehr merkwürdigen Unterschied zwischen unseren Python-Installationen oder der Quelltext den Du gezeigt hast stimmt nicht mit dem überein den Du tatsächlich laufen lässt.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Oder aber die gezeigte Testdatei stimmt nicht mit der tatsächlichen Datei überein, was ziemlich wahrscheinlich sein dürfte. Dann sollte man beim "Verallgemeinern" der Daten darauf achten, dass man nicht zu weit vom Original abweicht. Ich sehe in der Testdatei jedenfalls nur einmal doppelte Anführungsstriche. Normalerweise müsste es ja noch ein Gegenstück geben, um den "Anführungsabschnitt" zu beenden.
kidchino
User
Beiträge: 91
Registriert: Montag 17. November 2014, 14:18

Hey,
@snafu
snafu hat geschrieben:Ich sehe in der Testdatei jedenfalls nur einmal doppelte Anführungsstriche. Normalerweise müsste es ja noch ein Gegenstück geben, um den "Anführungsabschnitt" zu beenden.
Das ist ja mein Problem gewesen. Die Dateien, die ich nutze haben häufig nur ein Anführungszeichen und das zweite fehlt. D.h. (so wie ich es sehe) wird der "Anführungsabschnitt" automatisch beendet und zwar bei C3, also am Ende des Inhalt.
snafu hat geschrieben:Oder aber die gezeigte Testdatei stimmt nicht mit der tatsächlichen Datei überein, was ziemlich wahrscheinlich sein dürfte
Die Beispieldateien, die ich hier zeige sind 1zu1 die mit denen ich derzeit arbeite. Ich nutze diese vereinfachten Beispiele damit ich einfacher printen etc kann und so den Fehler ggf schnell finde. In den Orginaldateien ist das Schema und die Trennung exakt gleich, nur sind es 65 Elemente pro Zeile, 501 Zeilen und teilweise 100.000 Zeichen pro Element. Dadurch wird dann ein print an diversen Stellen ziemlich unsinnig, wenn ich schauen will, welche Werte gerade eine Variable hat und mir dann der Bildschirm mit Zeichen geflutet wird und ich nicht mal weiß wo ich die Werte in der Ursprungsdatei finden kann.

Hier ist dann das vollständige Skript, das dann auch eine Datei ausspuckt:
Ich dachte es wäre unsinnig für die Frage wie man ein Anführungszeichen ersetzt.

Code: Alles auswählen

# -*- coding: utf-8 -*-
#Das Skript schreibt alle Zeilen aus allen Dateien eines Ordner in eine großes Datei und hängt den Datennamen hinten dran (4 Zellen)
import csv, os, sys, re

pfad = 'C:/Skripttesten/papererweiterung/1/' # relevanter Pfad mit Dateien

liste_dateiname = os.listdir(pfad) # Pfad zu den txt/csv Dateien 'Pfad'
csv.field_size_limit(250000)
liste = [] #erstellt eine leeres Array
gesamte_datei = open('C:/Skripttesten/papererweiterung1/test.csv', "wb")  #öffne die gesamte Datei
for dateiname in liste_dateiname:   # für jedes Element der Variable path 
        
    with open(os.path.join(pfad, dateiname), "rb") as f: #öffnet die jeweilige datei
        reader = csv.reader(f, delimiter="\t") #liest die zeilen aus, tabstop getrennt
        next(reader) #überspringt jeweils die erste zeile 
        
        for row in reader:   #schleife für jede zeile
            #if row[58] <> "": # prüft nur ob 58 nicht leer ist. die darf eigentlich nicht leer sein
             #  paperIdOhneWos = row[58].replace ("WOS:", "") #entfernt in Spalten 58 das WOS von der Paper-No und schreibt es in die Var. paperIdOhneWos
              # row.append(paperIdOhneWos) #hängt paperIdOhneWos hinten als Spalte dran
                #print (paperIdOhneWos)
            #spalte1 = row[1]
            #spalte1= spalte1.replace('\"','x')
            row = [cell.replace('\"', 'x') for cell in row]
            #print(spalte1,row[1])
            liste.append(row) #schreibt die zeilen in die liste

writer = csv.writer(gesamte_datei,  delimiter = "\t")#gibt die liste weiter an die gesamte datei
writer.writerows(liste)#gibt die liste weiter an die gesamte datei
print("Ende - Dateien zusammengefuegt", gesamte_datei.name)

@Siruis3
Sirius3 hat geschrieben:Du mußt einfach für alle Spalten replace aufrufen:
Danke.
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@kidchino: das Geheimnis ist die Behandlung der Anführungszeichen, die normalerweise dazu benutzt werden, dass auch csv-Trennzeichen in einer Zelle vorkommen dürfen, bei Dir aber nur Schrott zu sein scheinen. Daher muß man die Anführungszeichenbehandlung abschalten (quotechar=None).

Code: Alles auswählen

# -*- coding: utf-8 -*-
#Das Skript schreibt alle Zeilen aus allen Dateien eines Ordner in eine großes Datei und hängt den Datennamen hinten dran (4 Zellen)
import csv
import os
 
pfad = 'C:/Skripttesten/papererweiterung/1/' # relevanter Pfad mit Dateien
csv.field_size_limit(250000)
with open('C:/Skripttesten/papererweiterung1/test.csv', "wb") as gesamte_datei:
    writer = csv.writer(gesamte_datei,  delimiter = "\t")
    for dateiname in os.listdir(pfad):
        with open(os.path.join(pfad, dateiname), "rb") as f:
            reader = csv.reader(f, delimiter="\t", quotechar=None)
            next(reader)
            writer.writerows(
                [cell.replace('"', 'x') for cell in row]
                for row in reader
            )
PS: Die ganzen Kommentare machen Deinen Code ziemlich unleserlich.
kidchino
User
Beiträge: 91
Registriert: Montag 17. November 2014, 14:18

Hi Sirius3,

ahh danke. Auch für die Erklärung.
Das ist das richtige Wort:
Sirius3 hat geschrieben:bei Dir aber nur Schrott zu sein scheinen.
Aber jetzt nochmal eine dumme Frage.
Es sind ja bei mir "wahrscheinlich" eingescannte Daten. Daher der angesproche Schrott von oben.
Wenn nun ich nur ein Element mit nem Text hätte, bspw. so:

Code: Alles auswählen

"HI testen wir mal heute nachmittag" 
und es durch einen fehlerhaften Scan zu

Code: Alles auswählen

"H\testen wir mal heute nachmittag" 
wird(also ein "\t" entsteht.), dann habe ich ein Problem oder?

LG
BlackJack

@kidchino: Ja, dann hast Du ein Problem. Das bestünde nicht wenn das beim erstellen der CSV-Dateien korrekt gequoted würde, aber das scheint ja auch nicht der Fall zu sein weil Du für's lesen die Quote-Behandlung ja gerade eben erst abgeschaltet hast.

Wenn man kaputte Daten als Ausgang hat kann man die halt nicht 100% sicher automatisiert verarbeiten. Denken können Rechner (immer) noch nicht. Ist vielleicht auch besser so, sonst hätten sie wahrscheinlich schon die Welthersschaft an sich gerissen. ;-)
kidchino
User
Beiträge: 91
Registriert: Montag 17. November 2014, 14:18

BlackJack hat geschrieben:Ja, dann hast Du ein Problem.
Ach man, nach den Problemen ist vor den Problemen...Ist sitze in zwei Jahren bestimmt immer noch an diesen *geflucht* Daten.
BlackJack hat geschrieben:Welthersschaft
Das prophezeit der gute Stephen Hawking ja gerade ;)

Danke!
LG
kid
kidchino
User
Beiträge: 91
Registriert: Montag 17. November 2014, 14:18

Hi zusammen,
ich habe nun das richtige Problem gefunden:
So sieht die Datei aus (tabstopp getrennt)

Code: Alles auswählen

A1      B1\     C1
A2      B2      C2
A3      B3      C3
Und natürlich wird daraus:

Code: Alles auswählen

A1      B1C1
A2      B2      C2
A3      B3      C3
Wie würdet Ihr da vernünftigerweise mit umgehen.
Ich dachte jetzt, dass ich versuche alle \ zu ersetzen, oder?
VG
kid
BlackJack

@kidchino: Wieso sollte aus der Eingabe ”natürlich” die von Dir gezeigte Ausgabe werden? Bei mir nicht. Ich konnte bisher noch kein Problem von Dir hier wirklich nachvollziehen, also was Code und Daten angeht. Entweder funktionierte der Code gar nicht weil ich eine Ausnahme bekommen habe statt eines Ergebnisses, oder das Ergebnis stimmte nicht mit dem überein was Du behauptest was angeblich passiert.
kidchino
User
Beiträge: 91
Registriert: Montag 17. November 2014, 14:18

Hallo BlackJack, frohes neues Jahr,

ich habe diese Inputdaten
kidchino hat geschrieben:Code: [Alles auswählen] [Aufklappen/Zusammenklappen]

A1 B1\ C1
A2 B2 C2
A3 B3 C3
Und lese diese dann in eine Mysql Datenbank. Und dort wird dann immer das hier draus:
kidchino hat geschrieben:A1 B1C1
A2 B2 C2
A3 B3 C3
Ich weiß nicht, wie in die Mysql-Tabelle anders formatieren soll/ kann, damit einzelne "\" ignoriert werden.
Und deswegen wollte ich diesen Fehler im Vorfeld eliminieren und das "\" überall entfernen.

LG
kid
BlackJack

@kidchino: Das hat dann jetzt aber doch gar nichts damit zu tun wie die Daten in Python gelesen und geschrieben werden, sondern was *MySQL* erwartet. Ich gehe mal davon aus dass das irgendwo dokumentiert ist wie die Daten für einen Import aufgebaut sein müssen und welche Zeichen oder Zeichenkombinationen dabei eine spezielle Bedeutung haben. Und wie man das verhindert.
Antworten