2015-02-25 13 views
5

Próbuję parsować pliki CSV z zewnętrznego systemu, nad którym nie mam kontroli.Jak obsługiwać podwójne cudzysłowy wewnątrz wartości pól za pomocą modułu CSV?

  • przecinek jest używany jako separator
  • gdy komórka zawiera przecinek wtedy to owinięte w cudzysłowach i wszystkie inne cytaty uciekła z innym znak.
  • (Mój problem), gdy komórka nie była zawijana w cudzysłowy, wszystkie znaki cudzysłowu są jednak wymieniane z inną kwotą.

Przykład CSV:

qw "" erty "A" "B" "C" "D EF" "" "G"

mają być analizowane jako:

[['qw"erty', 'a"b"c"d,ef""g']] 

Myślę jednak, że moduł csv Pythona nie spodziewa cudzysłowów być uciekł, gdy komórka nie była zawinięta w cytując znaków w pierwszej kolejności. csv.reader(my_file) (z domyślnie doublequote=True) zwraca:

['qw""erty', 'a"b"c"d,ef""g'] 

Czy istnieje jakiś sposób, aby analizować to z modułem python csv?

+2

Dlaczego nie zastąpić wszystkie wystąpienia '„«»”' wewnątrz podwójnych cytatów z '„\\ "” '' csv' Następnie czytelnik powinien być w stanie pracować normalnie –

+2

Twój cudzysłów i znak ucieczki są takie same? –

+0

Fragment @JackManey "wewnątrz podwójnych cytatów" był niepotrzebny, ale ogólnie myślę, że zadziała, pod warunkiem, że uniknę też wszystkich znaków \ ​​'. – matf

Odpowiedz

4

Nawiązując @JackManey komentarzu gdzie zasugerował, aby zastąpić wszystkie wystąpienia '""' wewnątrz podwójnych cytatów z '\\"'.

Rozpoznanie, czy jesteśmy obecnie wewnątrz podwójnie cytowanych komórek okazało się niepotrzebne i możemy zastąpić wszystkie wystąpienia '""' przez '\\"'. Python documentation says:

Na czytaniu escapechar usuwa wszelkie szczególne znaczenie z poniższej charakteru

Jednak byłoby to nadal łamać w przypadku, gdy oryginalna komórka zawiera już uciec znaków Przykład: 'qw\\\\""erty' produkującej [['qw\\"erty']]. Musimy więc uciec przed znakami ucieczki przed analizą.

rozwiązanie końcowa:

with open(file_path, 'rb') as f: 
    content = f.read().replace('\\', '\\\\').replace('""', '\\"') 
    reader = csv.reader(StringIO(content), doublequote=False, escapechar='\\') 
    return [row for row in reader] 
0

, jak sugeruje @JackManey, po przeczytaniu pliku można zastąpić podwójny cudzysłów jedno-podwójną kwotą.

my_file_onequote = [col.replace('""', '"') for col in row for row in my_file] 
+2

To się nie powiedzie z "ab "" cd, ef "zwraca 2 komórki, jednak @JackManey ma prawie rację, jak sądzę. – matf

Powiązane problemy