Seite 1 von 1

Anführungszeichen ersetzen

Verfasst: Donnerstag 11. Dezember 2014, 15:48
von kidchino
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

Re: Anführungszeichen ersetzen

Verfasst: Donnerstag 11. Dezember 2014, 16:06
von mutetella
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

Re: Anführungszeichen ersetzen

Verfasst: Montag 15. Dezember 2014, 10:09
von kidchino
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

Re: Anführungszeichen ersetzen

Verfasst: Montag 15. Dezember 2014, 10:44
von Sirius3
@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]

Re: Anführungszeichen ersetzen

Verfasst: Montag 15. Dezember 2014, 11:54
von 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

Re: Anführungszeichen ersetzen

Verfasst: Montag 15. Dezember 2014, 14:28
von kidchino
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

Re: Anführungszeichen ersetzen

Verfasst: Montag 15. Dezember 2014, 14:47
von 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.

Re: Anführungszeichen ersetzen

Verfasst: Montag 15. Dezember 2014, 14:55
von kidchino
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

Re: Anführungszeichen ersetzen

Verfasst: Montag 15. Dezember 2014, 15:17
von 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.

Re: Anführungszeichen ersetzen

Verfasst: Montag 15. Dezember 2014, 16:38
von snafu
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.

Re: Anführungszeichen ersetzen

Verfasst: Dienstag 16. Dezember 2014, 10:12
von kidchino
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.

Re: Anführungszeichen ersetzen

Verfasst: Dienstag 16. Dezember 2014, 12:02
von Sirius3
@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.

Re: Anführungszeichen ersetzen

Verfasst: Dienstag 16. Dezember 2014, 12:12
von kidchino
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

Re: Anführungszeichen ersetzen

Verfasst: Dienstag 16. Dezember 2014, 12:23
von 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. ;-)

Re: Anführungszeichen ersetzen

Verfasst: Dienstag 16. Dezember 2014, 12:37
von kidchino
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

Re: Anführungszeichen ersetzen

Verfasst: Freitag 19. Dezember 2014, 13:42
von kidchino
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

Re: Anführungszeichen ersetzen

Verfasst: Freitag 19. Dezember 2014, 13:53
von 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.

Re: Anführungszeichen ersetzen

Verfasst: Montag 5. Januar 2015, 09:00
von kidchino
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

Re: Anführungszeichen ersetzen

Verfasst: Montag 5. Januar 2015, 11:26
von 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.