CSVで二重引用符を適切にエスケープする


164

CSVに次のような行があります。

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

隣の引用24はインチを表すために使用され、そのすぐ隣の引用はフィールドを閉じます。私は行を読んでいますfgetcsvが、パーサーは間違いを犯し、値を次のように読みます:

Samsung U600 24",10000003409"

インチの引用符の前にバックスラッシュを付けてみましたが、名前にバックスラッシュが付きます:

Samsung U600 24\"

これをCSVで適切にエスケープして値がになるようにする方法はありますかSamsung U600 24"、またはプロセッサで正規表現する必要がありますか?


21
見積もりを2倍にします。以上です
常識

回答:


281

2つの引用符を使用します。

"Samsung U600 24"""

101
RFC-4180、段落「フィールドを囲むために二重引用符を使用する場合、フィールド内に表示される二重引用符は、その前に別の二重引用符を付けることでエスケープする必要があります。」
2015

4
tommedが言うように、二重引用符をエスケープするには、単一の二重引用符を追加する必要があるだけです。csvfixというコマンドラインツールを使用して、準拠していない行を検出できます。csvfixcheck -nl -v [filename]
Sam Critchley

2
@SamCritchleyここでエスケープするために使用されているのは単一の二重引用符だけです。「2つの引用符を使用」により、user4035は1つの引用符が2つの引用符に置き換えられることを意味します。二重引用符を二重引用符でエスケープすることにより、二重引用符のペア(2つの二重引用符)を効率的に作成できます。最後に表示される最後の引用は、フィールドを終了することです。
Zenexer 2016

1
一重二重二重一重二重引用符が必要ですが、二重一重二重引用符が続く場合のみ...幸運を祈ります!
Daniel Waltrip

14

二重引用符だけでなく、単一引用符(')、二重引用符(")、バックスラッシュ(\)、NUL(NULLバイト)も必要になります。

すべてを処理fputcsv()する書き込みとfgetcsv()読み取りに使用します。


3
このコメントのドキュメントページfputcsv()は、使用方法を示していfputcsv()ますが、ブラウザの代わりに、実際のファイルにCSV形式で出力したいとき。
dennisschagt 2015年

15
@Angelin Nadar、一重引用符、バックスラッシュ、NULの二重化の必要性について、ソースを追加してください。RFC-4180では見つかりませんでした。
Petr 'PePa' Pavel

2
一重引用符などを実際にエスケープする必要はありません。適切なCSVファイルでは、一重引用符のみを含むフィールドを二重引用符で囲む必要もありません。CSVリーダーが適切に実装されていれば、これらの記号が付いていてもファイルを正しく読み取ることができます。
xji

4
なぜこの回答は投票されたのですか?文字のエスケープに関するコメントはバックアップされておらず、元の質問ではPHPについて尋ねられていません。Open Officeなどのプログラムで変更できる場合、これは文字列区切り文字(および選択した区切り文字)にのみ当てはまるようです。
Dave F

0

私はこれが古い投稿であることを知っていますが、拡張メソッドを使用してC#で(null値を空の文字列に変換して)解決する方法を次に示します。

次のような静的クラスを作成します。

    /// <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;
    }

次に、CSVに書き込む文字列ごとに、次の代わりに:

stringBuilder.Append( WhateverVariable );

あなただけです:

stringBuilder.Append( WhateverVariable.Q() );

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.