Poprawnie unikaj podwójnego cudzysłowu w CSV


164

Mam taką linię w moim pliku CSV:

"Samsung U600 24"","10000003409","1","10000003427"

Cudzysłów obok 24służy do wyrażenia cali, natomiast cudzysłów tuż obok tego cudzysłowu zamyka pole. Czytam wiersz, fgetcsvale parser popełnia błąd i odczytuje wartość jako:

Samsung U600 24",10000003409"

Próbowałem wstawić ukośnik odwrotny przed cudzysłowem w calach, ale w nazwie po prostu otrzymuję ukośnik odwrotny:

Samsung U600 24\"

Czy istnieje sposób, aby odpowiednio uciec od tego w CSV, aby wartość była Samsung U600 24", czy też muszę to regexować w procesorze?


21
Po prostu podwoj swoją ofertę. To wszystko
Twój zdrowy rozsądek

Odpowiedzi:


281

Użyj 2 cudzysłowów:

"Samsung U600 24"""

102
RFC-4180, akapit „Jeśli do ujęcia pól używane są cudzysłowy podwójne, wówczas znak podwójnego cudzysłowu pojawiający się wewnątrz pola musi zostać poprzedzony innym cudzysłowem”.
tommed

4
Jak mówi tommed, wystarczy dodać pojedynczy podwójny cudzysłów, aby uniknąć podwójnego cudzysłowu. Możesz użyć narzędzia wiersza poleceń o nazwie csvfix, aby wykryć wszelkie niezgodne wiersze: csvfix check -nl -v [nazwa pliku]
Sam Critchley

2
@SamCritchley Widzę tutaj tylko pojedynczy podwójny cudzysłów, aby uciec. Poprzez „Użyj 2 cudzysłowów” user4035 oznacza, że ​​1 cytat należy zastąpić 2 cudzysłowami. Unikając podwójnych cudzysłowów cudzysłowami podwójnymi, skutecznie tworzysz pary cudzysłowów (2 cudzysłowy). Ostatnim cytatem, który widzisz na końcu, jest zakończenie pola.
Zenexer

1
wymagane są pojedyncze podwójne podwójne pojedyncze podwójne cudzysłowy, ale tylko wtedy, gdy poprzedzone są podwójnym, pojedynczym podwójnym cudzysłowem ... powodzenia!
Daniel Waltrip,

14

Nie tylko podwójne cudzysłowy, będziesz potrzebować pojedynczego cudzysłowu ( '), podwójnego cudzysłowu ( "), ukośnika odwrotnego ( \) i NUL (bajt NULL).

Służy fputcsv()do pisania i fgetcsv()czytania, co zadba o wszystko.


3
Ten komentarz na stronie dokumentacjifputcsv() pokazuje, jak możesz użyć, fputcsv()gdy chcesz wyświetlać w przeglądarce w formacie csv zamiast rzeczywistego pliku.
dennisschagt

15
@Angelin Nadar, czy mógłbyś dodać źródło do swojego twierdzenia o potrzebie podwójnego cudzysłowu, ukośnika odwrotnego i NUL? Nie znalazłem tego w RFC-4180 .
Petr 'PePa' Pavel

2
W rzeczywistości nie musisz zmieniać cudzysłowów itp. Właściwy plik CSV nie musi nawet dodawać podwójnych cudzysłowów wokół pola, które zawiera tylko pojedyncze cudzysłowy. Jeśli czytnik CSV jest poprawnie zaimplementowany, powinien poprawnie odczytać plik, nawet z tymi symbolami.
xji,

4
Dlaczego ta odpowiedź została kiedykolwiek przegłosowana? Komentarz o ucieczce znaków nigdy nie został zarchiwizowany, a oryginalne pytanie nie dotyczy PHP. Wydaje się, że jest to prawdą tylko dla ogranicznika ciągu (i tylko dla wybranego separatora), gdy program, taki jak Open Office, pozwala na jego zmianę.
Dave F

0

Wiem, że to stary post, ale oto jak go rozwiązałem (wraz z konwersją wartości null na pusty ciąg) w C # przy użyciu metody rozszerzenia.

Utwórz klasę statyczną z czymś podobnym do następującego:

    /// <summary>
    /// Wraps value in quotes if necessary and converts nulls to empty string
    /// </summary>
    /// <param name="value"></param>
    /// <returns>String ready for use in CSV output</returns>
    public static string Q(this string value)
    {
        if (value == null)
        {
            return string.Empty;
        }
        if (value.Contains(",") || (value.Contains("\"") || value.Contains("'") || value.Contains("\\"))
        {
            return "\"" + value + "\"";
        }
        return value;
    }

Następnie dla każdego ciągu, który piszesz do CSV, zamiast:

stringBuilder.Append( WhateverVariable );

Po prostu zrób:

stringBuilder.Append( WhateverVariable.Q() );

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.