CSVファイルでのカンマの処理


472

作成され、お客様によってアップロードされたcsvファイルの処理方法に関する提案を探しています。会社名などの値にコンマが含まれている可能性があります。

私たちが見ているいくつかのアイデアは、引用符で囲まれた識別子(値 "、"値 "、"など)または| カンマの代わりに。最大の問題は、私たちがそれを簡単にしなければならない、または顧客がそれをしないということです。


顧客がそれを書いてアップロードしている
Bob The Janitor

1
これがcsvファイルで内部のcommosを管理するソリューションです。stackoverflow.com/questions/9889225/…に
Hasan Abrar 2014

iOSでは、基本的にgithub.com/Flinesoft/CSVImporterを使用する 必要があります
Fattie

3
このQAは古いことに注意してください。今日のcsvはRFC 4180意味し、それはそれだけです。
Fattie

私はまったく同じ問題を抱えており、カンマ区切りのcsvファイルの列を合計しようとしています。awkコマンドで問題ありません。残念ながら、一部のセルにはカンマが含まれている場合があります(アドレスなど)。他のセルには含まれません。Linux互換のソリューションを探していますが、どこから始めればよいかわかりません。
Greenage

回答:


223

他の人が言ったように、引用符を含む値をエスケープする必要があります。以下は、埋め込まれた引用符や改行を含む引用符付きの値をサポートするC♯の小さなCSVリーダーです。

ちなみに、これは単体テスト済みのコードです。この質問は非常に多く出てきたようで、簡単なCSVサポートでライブラリ全体を必要としない人がいるかもしれないので、現在投稿しています。

次のように使用できます。

using System;
public class test
{
    public static void Main()
    {
        using ( CsvReader reader = new CsvReader( "data.csv" ) )
        {
            foreach( string[] values in reader.RowEnumerator )
            {
                Console.WriteLine( "Row {0} has {1} values.", reader.RowIndex, values.Length );
            }
        }
        Console.ReadLine();
    }
}

ここにクラスがあります。このCsv.Escape関数を使用して、有効なCSVを書き込むこともできます。

using System.IO;
using System.Text.RegularExpressions;

public sealed class CsvReader : System.IDisposable
{
    public CsvReader( string fileName ) : this( new FileStream( fileName, FileMode.Open, FileAccess.Read ) )
    {
    }

    public CsvReader( Stream stream )
    {
        __reader = new StreamReader( stream );
    }

    public System.Collections.IEnumerable RowEnumerator
    {
        get {
            if ( null == __reader )
                throw new System.ApplicationException( "I can't start reading without CSV input." );

            __rowno = 0;
            string sLine;
            string sNextLine;

            while ( null != ( sLine = __reader.ReadLine() ) )
            {
                while ( rexRunOnLine.IsMatch( sLine ) && null != ( sNextLine = __reader.ReadLine() ) )
                    sLine += "\n" + sNextLine;

                __rowno++;
                string[] values = rexCsvSplitter.Split( sLine );

                for ( int i = 0; i < values.Length; i++ )
                    values[i] = Csv.Unescape( values[i] );

                yield return values;
            }

            __reader.Close();
        }
    }

    public long RowIndex { get { return __rowno; } }

    public void Dispose()
    {
        if ( null != __reader ) __reader.Dispose();
    }

    //============================================


    private long __rowno = 0;
    private TextReader __reader;
    private static Regex rexCsvSplitter = new Regex( @",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))" );
    private static Regex rexRunOnLine = new Regex( @"^[^""]*(?:""[^""]*""[^""]*)*""[^""]*$" );
}

public static class Csv
{
    public static string Escape( string s )
    {
        if ( s.Contains( QUOTE ) )
            s = s.Replace( QUOTE, ESCAPED_QUOTE );

        if ( s.IndexOfAny( CHARACTERS_THAT_MUST_BE_QUOTED ) > -1 )
            s = QUOTE + s + QUOTE;

        return s;
    }

    public static string Unescape( string s )
    {
        if ( s.StartsWith( QUOTE ) && s.EndsWith( QUOTE ) )
        {
            s = s.Substring( 1, s.Length - 2 );

            if ( s.Contains( ESCAPED_QUOTE ) )
                s = s.Replace( ESCAPED_QUOTE, QUOTE );
        }

        return s;
    }


    private const string QUOTE = "\"";
    private const string ESCAPED_QUOTE = "\"\"";
    private static char[] CHARACTERS_THAT_MUST_BE_QUOTED = { ',', '"', '\n' };
}

2
アプリケーションによっては、Windowsに準拠するために\ r \ nの翻訳も必要になる場合があります。
Mandrake

3
@NadaNaeem、詳しく説明しますか?
harpo 2015

それはcsvファイル行の項目を正しく数えていません。フィールドのカンマと勇気の戻りとタップをうまく処理していません
Nada N. Hantouli

-1 OPは、ファイルを作成する言語を指定しません。C#以外の言語でソリューションを探している他のプログラマーがここに来た場合、彼らはこの回答で使用できるソリューションを見つけることができません。
Ben Leggiero、2015年

8
@ BenC.R.Leggiero、それではあなたの質問にも反対票を投じる必要があると思います。それはあなたの標準では答えられないからです。実際のコードは単純な仕様の正式な実装に相当し、一般的に使用されている言語に簡単に翻訳できます。
harpo 2015年

395

2017年の場合、csvは完全に指定されています-RFC 4180。

これは非常に一般的な仕様であり、多くのライブラリ()で完全にカバーされています。

簡単に入手できるcsvライブラリを使用するだけです。つまり、RFC 4180です。


実際にはCSV形式の仕様とコンマの処理方法があります。

改行(CRLF)、二重引用符、およびコンマを含むフィールドは、二重引用符で囲む必要があります。

http://tools.ietf.org/html/rfc4180

したがって、値foobar,bazを使用するには、次のようにします。

foo,"bar,baz"

考慮すべきもう1つの重要な要件(これも仕様から):

フィールドを囲むために二重引用符を使用する場合、フィールド内に表示される二重引用符は、その前に別の二重引用符を付けることでエスケープする必要があります。例えば:

"aaa","b""bb","ccc"

120
「改行(CRLF)、二重引用符、およびコンマを含むフィールドは、二重引用符で囲む必要があります。」
Eli、

42
「フィールドを囲むために二重引用符を使用する場合、フィールド内に表示される二重引用符は、その前に別の二重引用符を付けることでエスケープする必要があります。」
C.ドラゴン76

11
実際には仕様ではありませんが、おそらく便利です。「CSVファイルのさまざまな解釈を可能にする正式な仕様は存在しません。このセクションでは、ほとんどの実装が従うと思われる形式について説明します。」
Justin Clarke

5
また、その名前にもかかわらず、少なくともWindowsプラットフォームでは、行内のCSV値がコンマで区切られていない場合があることを忘れないでください。これは、現在の地域設定(コマンドラインのintl.cpl、「詳細設定」)、特にリスト区切り文字に依存しますSystem.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator
lxa 2013

4
この回答には、リンクに加えて、関連情報を入力してください。A)上記のコメント(および私のコメント)のほとんどを削除します。B)回答者よりもはるかに多くの人を救い、さらに別のページに移動して関連するものを見つけます。データ、C)リンクの腐敗を防ぐ。
user66001 2015

76

CSV形式では、値を区切るためにコンマを使用します。キャリッジリターン、ラインフィード、コンマ、または二重引用符を含む値は、二重引用符で囲まれます。二重引用符を含む値は引用符で囲まれ、各リテラル引用符は直前の引用符でエスケープされます。たとえば、3つの値:

test
list, of, items
"go" he said

次のようにエンコードされます:

test
"list, of, items"
"""go"" he said"

任意のフィールドを引用できますが、引用符で囲む必要があるのは、コンマ、CR / NL、または引用符を含むフィールドのみです。

CSV形式には実際の標準はありませんが、ほとんどすべてのアプリケーションはここに記載されている規則に従います。他の場所で言及されたRFCはCSVの標準ではありません。これはMIME内でCSVを使用するためのRFCであり、MIMEの外では役に立たない、従来とは異なる不要な制限が含まれています。

私が見た多くのCSVモジュールが対応していないことの問題は、複数の行が単一のフィールドにエンコードされる可能性があるという事実です。つまり、各行が個別のレコードであると想定できないため、改行を許可しない必要があります。データまたはこれを処理する準備をしてください。


40

文字列を二重引用符で囲みます。これは一般的にExcelが行うことです。

アラ・エリ、

二重引用符を2つの二重引用符としてエスケープします。例:「test1」、「foo」、「bar」、「test2」


基本的に、引用された識別子と同じコンセプト
Bob The Janitor '20

1
二重引用符を2つの二重引用符としてエスケープします。たとえば、「test1」、「foo」、「bar」、「test2」
Eli

「カンマの直後されたときにだけ、文字列を二重引用符を置くことは動作しません
MondKin

9

フィールドを二重引用符で囲むことができます。別の特殊文字(二重引用符)が追加されるため、このアプローチは好きではありません。エスケープ文字(通常はバックスラッシュ)を定義し、何かをエスケープする必要がある場合はどこでも使用できます。

データ、より多くのデータ、より多くのデータ\、さらに、さらに

引用符を一致させる必要はなく、解析する例外も少なくなります。これにより、コードも簡素化されます。


3
「\」を含むエントリが実際にある場合、迅速かつダーティですが機能しません
Sarp Kaya

1
Sarp、それが二重の\\がエスケープされたバックスラッシュである理由です。これは、もう1つの特殊文字になるからです。
グルンゴンドーラ2015年

1
これは機能しますが、CSVではありません。それはですDSV
TRiG 2016年

8

ほぼすべての整形式CSV(.net)を処理するためにnugetを介して利用可能なライブラリがあります-CsvHelper

クラスにマップする例:

var csv = new CsvReader( textReader );
var records = csv.GetRecords<MyClass>();

個々のフィールドを読み取る例:

var csv = new CsvReader( textReader );
while( csv.Read() )
{
    var intField = csv.GetField<int>( 0 );
    var stringField = csv.GetField<string>( 1 );
    var boolField = csv.GetField<bool>( "HeaderName" );
}

クライアントにファイル形式を操作させる:
,は標準のフィールド区切り文字です。これは、"区切り文字、引用符、または行末を含むフィールドをエスケープするために使用される標準値です。

(たとえば)#フィールドや'エスケープに使用するには:

var csv = new CsvReader( textReader );
csv.Configuration.Delimiter = "#";
csv.Configuration.Quote = ''';
// read the file however meets your needs

その他のドキュメント


3
CsvHelperライブラリを使用してOPの問題を解決する方法の例を含めた方がよいでしょう。
ジョージストッカー2014年

.Netのほぼすべてが「ヘルパー」になる理由...この言葉はほとんど意味がありません...「マネージャー」のようです。
bytedev

5

ハーポの答えに対する私のコメントで述べたように、彼の解決策は優れていてほとんどの場合に機能しますが、いくつかのシナリオでは、カンマが互いに直接隣接しているため、カンマで分割できません。

これは、Regex文字列がvertabim文字列として予期しない動作をするためです。これを正しく動作させるには、正規表現文字列内のすべての文字を、vertabimエスケープを使用せずに手動でエスケープする必要があります。

つまり。正規表現は、手動エスケープを使用してこれである必要があります。

",(?=(?:[^\"\"]*\"\"[^\"\"]*\"\")*(?![^\"\"]*\"\"))"

それは ",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))"

vertabim文字列を使用する@",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))"場合、正規表現をデバッグするかどうかを確認できるように、次のように動作します。

",(?=(?:[^"]*"[^"]*")*(?![^"]*"))"

要約すると、私はharpoのソリューションをお勧めしますが、この小さな問題に注意してください!

このエラーが発生した場合に通知するために、CsvReaderにオプションのフェイルセーフをいくつか組み込んでいます(既知の数の列がある場合)。

if (_expectedDataLength > 0 && values.Length != _expectedDataLength) 
throw new DataLengthException(string.Format("Expected {0} columns when splitting csv, got {1}", _expectedDataLength, values.Length));

これはコンストラクタを介して注入できます:

public CsvReader(string fileName, int expectedDataLength = 0) : this(new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
    _expectedDataLength = expectedDataLength;
}

ヘッダー行をどのように処理しますか?csvをすべての型であるC#オブジェクトにマップしようとしていますが、ヘッダー行はすべての文字列が原因で壊れています...
tCoe

[^""]と同じではありません[^"]か?文字クラス仕様内の文字の重複は冗長ですよね?
Minh Tran

4

Microsoft.VisualBasicへの参照を追加します(はい、VisualBasicと表示されていますが、C#でも同様に機能します。最後に、すべてがILであることを思い出してください)。

Microsoft.VisualBasic.FileIO.TextFieldParserクラスを使用してCSVファイルを解析する以下はサンプルコードです。

 Dim parser As TextFieldParser = New TextFieldParser("C:\mar0112.csv")
 parser.TextFieldType = FieldType.Delimited
 parser.SetDelimiters(",")      

   While Not parser.EndOfData         
      'Processing row             
      Dim fields() As String = parser.ReadFields         
      For Each field As String In fields             
         'TODO: Process field                   

      Next      
      parser.Close()
   End While 

はい、これはやや残念な名前空間で非常に便利なクラスです;-)。ただし、元の質問に対処するには、設定parser.HasFieldsEnclosedInQuotes = true;する必要があります。また、CSV仕様に従って、入力ファイルは引用符でコンマを含むフィールドを囲む必要があります。Excelはこれをすでに行っています。
クリストファーキング


4

場合は、あなたがにしているの* nixシステムへのアクセスを持っているsedと1つの以上存在することができだけで、不要なカンマ特定のフィールドあなたのCSVの、あなたはそれらを囲むために、次のワンライナーを使用することができる"ようにRFC4180のセクション2提案:

sed -r 's/([^,]*,[^,]*,[^,]*,)(.*)(,.*,.*)/\1"\2"\3/' inputfile

不要なカンマが含まれているフィールドによっては、正規表現のキャプチャグループ(および置換)を変更または拡張する必要があります。
上記の例では、4番目のフィールド(6つのうち)を引用符で囲みます。

ここに画像の説明を入力してください

--in-place-optionと組み合わせて、これらの変更をファイルに直接適用できます。

正しい正規表現を「構築」するために、従うべき単純な原則があります。

  1. 不要なカンマが含まれるフィールドの前にあるCSVのすべてのフィールドについて、1つを記述[^,]*,し、それらすべてをキャプチャグループにまとめます。
  2. 不要なカンマが含まれているフィールドの場合は、と入力します(.*)
  3. 不要なコンマが含まれるフィールドののすべてのフィールド 1つ記述,.* して、それらをすべてキャプチャグループにまとめます。

以下は、特定のフィールドに応じて、考えられるさまざまな正規表現/置換の概要です。指定しない場合、置換はになり\1"\2"\3ます。

([^,]*)(,.*)                     #first field, regex
"\1"\2                           #first field, substitution

(.*,)([^,]*)                     #last field, regex
\1"\2"                           #last field, substitution


([^,]*,)(.*)(,.*,.*,.*)          #second field (out of five fields)
([^,]*,[^,]*,)(.*)(,.*)          #third field (out of four fields)
([^,]*,[^,]*,[^,]*,)(.*)(,.*,.*) #fourth field (out of six fields)

不要なカンマsedを引用符で囲むのではなく削除したい場合は、この回答を参照してください。


3

車輪を再発明したい場合は、次の方法が効果的です。

public static IEnumerable<string> SplitCSV(string line)
{
    var s = new StringBuilder();
    bool escaped = false, inQuotes = false;
    foreach (char c in line)
    {
        if (c == ',' && !inQuotes)
        {
            yield return s.ToString();
            s.Clear();
        }
        else if (c == '\\' && !escaped)
        {
            escaped = true;
        }
        else if (c == '"' && !escaped)
        {
            inQuotes = !inQuotes;
        }
        else
        {
            escaped = false;
            s.Append(c);
        }
    }
    yield return s.ToString();
}

3

ヨーロッパでは、この問題はこの質問よりも早くする必要があります。ヨーロッパでは、小数点にはすべてカンマを使用します。以下のこの番号を参照してください。

| American      | Europe        |
| ------------- | ------------- |
| 0.5           | 0,5           |
| 3.14159265359 | 3,14159265359 |
| 17.54         | 17,54         |
| 175,186.15    | 175.186,15    |

そのため、CSVファイルにカンマ区切りを使用することはできません。そのため、ヨーロッパのCSVファイルはセミコロン;)で区切られています。

Microsoft Excelのようなプログラムはセミコロンでファイルを読み取ることができ、セパレーターから切り替えることができます。\t区切り文字としてタブ()を使用することもできます。Supper Userからのこの回答を参照してください。


2

一般的なファイルの解析方法(例としてCSVを使用)に関するより教育的な演習に興味がある場合は、Julian Bucknallによるこの記事をチェックしてください。記事が乗り越えられないはるかに小さな問題に分解されるので、私はこの記事が好きです。最初に文法を作成し、適切な文法が完成したら、文法をコードに変換するのは比較的簡単で体系的なプロセスです。

この記事ではC#を使用しており、下部にコードをダウンロードするためのリンクがあります。



1

NuGetでSoftCircuits.CsvParserを使用するだけです。これらすべての詳細を処理し、非常に大きなファイルを効率的に処理します。また、必要に応じて、列をオブジェクトのプロパティにマッピングすることで、オブジェクトをインポート/エクスポートすることもできます。さらに、私のテストでは、一般的なCsvHelperの平均より約4倍高速であることを示しました。


0

これは一般的な慣行に関するものなので、経験則から始めましょう。

  1. CSVを使用せず、ライブラリでXMLを使用して、代わりにxmlファイルを読み書きします。

  2. CSVを使用する必要がある場合。適切に実行し、無料のライブラリを使用してCSVファイルを解析および保存します。

1)を正当化するために、ほとんどのCSVパーサーはエンコードに対応していないため、US-ASCIIを扱っていない場合は問題が発生します。たとえば、Excel 2002ではCSVをローカルエンコーディングで保存していますが、エンコーディングに関する注意はありません。CSV標準は広く採用されていません:(。一方、xml標準はよく採用されており、エンコーディングをかなりうまく処理します。

2)を正当化するために、ほとんどすべての言語に対して多数のcsvパーサーが存在するため、ソリューションが非常に単純に見えても、ホイールを再発明する必要はありません。

いくつか例を挙げると:

  • Pythonではcsvモジュールでビルドを使用します

  • perlの場合はCPANとText :: CSVを確認してください

  • PHPの場合、fgetcsv / fputcsv関数でビルドを使用します

  • JavaのチェックSuperCVSライブラリ

組み込みデバイスで解析しない場合は、手動で実装する必要はありません。


12
XMLが常に答えであるとは限りません。CSVは、高密度の表形式のデータ(スプレッドシートなど)が大量にある場合に適したジョブ形式です。これらのタグは多くのオーバーヘッドをもたらします。すべての行が同じ形式である場合、すべての値が何を表すかを明示する必要はありません。XMLは、複雑な階層データ、またはオプションのフィールドを持つレコードがある場合に最適です。いつもそうとは限りません。
アダムJaskiewicz 2009

理論的には、「タグ」によって多少のオーバーヘッドが発生しますが、問題が発生し始める実際のアプリケーションは考えられません。実用的な例はありますか?データを処理するには、csvの代わりにデータベースを使用する必要があります。データのシリアル化(バックアップ、データ交換)について話す場合、解析に5日ではなく1週間かかるかどうかは重要ですか?
Piotr Czapla 2009

2
基本的に、テーブルによって最もよく表されるデータがある状況。たとえば、毎回サンプリングする12の異なるセンサーからのデータがあり、その時点での各センサーのタイムスタンプと値を記録するとします。各レコードは同一です:タイムスタンプ、sensor0、sensor1、... sensor11。XMLは複雑で不規則なデータを表すのに最適ですが、すべての状況に対応できるわけではない、かなり重い形式です。KISS
アダムJaskiewicz 2009

10
一部の人々は問題を見て、「私は知っています、私はXMLを使います!」今、彼らは2つの問題を抱えています。
Adam Jaskiewicz、2009

私は完全にxmlがすべての答えではないことに同意します。特に、データベースの置き換えや構成ファイルにはあま​​り適していません。しかし、ここで問題となったのは、XMLが設計されたデータ交換に関するものでした。
Piotr Czapla 2009

0

あなたはこのようにcsvファイルを読むことができます。

これはスプリットを利用してスペースを処理します。

ArrayList List = new ArrayList();
static ServerSocket Server;
static Socket socket;
static ArrayList<Object> list = new ArrayList<Object>();


public static void ReadFromXcel() throws FileNotFoundException
{   
    File f = new File("Book.csv");
    Scanner in = new Scanner(f);
    int count  =0;
    String[] date;
    String[] name;
    String[] Temp = new String[10];
    String[] Temp2 = new String[10];
    String[] numbers;
    ArrayList<String[]> List = new ArrayList<String[]>();
    HashMap m = new HashMap();

         in.nextLine();
         date = in.nextLine().split(",");
         name = in.nextLine().split(",");
         numbers = in.nextLine().split(",");
         while(in.hasNext())
         {
             String[] one = in.nextLine().split(",");
             List.add(one);
         }
         int xount = 0;
         //Making sure the lines don't start with a blank
         for(int y = 0; y<= date.length-1; y++)
         {
             if(!date[y].equals(""))
             {   
                 Temp[xount] = date[y];
                 Temp2[xount] = name[y];
                 xount++;
             }
         }

         date = Temp;
         name =Temp2;
         int counter = 0;
         while(counter < List.size())
         {
             String[] list = List.get(counter);
             String sNo = list[0];
             String Surname = list[1];
             String Name = list[2];
             for(int x = 3; x < list.length; x++)
             {           
                 m.put(numbers[x], list[x]);
             }
            Object newOne = new newOne(sNo, Name, Surname, m, false);
             StudentList.add(s);
             System.out.println(s.sNo);
             counter++;
         }

0

まず、「CSVファイルでカンマを異なる方法で処理する必要があるのはなぜだと思いますか?」

私にとっての答えは、「CSVファイルにデータをエクスポートすると、フィールドのカンマが消えて、フィールドが複数のフィールドに分割され、元のデータにカンマが表示されるためです。」(これは、コンマがCSVフィールドの区切り文字であるためです。)

状況によっては、セミコロンをCSVフィールドの区切り文字として使用することもできます。

私の要件では、コンマのように見える単一の低9引用符などの文字を使用できます。

だから、これがGoでそれを行う方法です:

// Replace special CSV characters with single low-9 quotation mark
func Scrub(a interface{}) string {
    s := fmt.Sprint(a)
    s = strings.Replace(s, ",", "‚", -1)
    s = strings.Replace(s, ";", "‚", -1)
    return s
}

Replace関数の2番目のコンマのような文字は10進数の8218です。

ASCIIのみのテキストリーダーを持つクライアントがいる場合、このdecima 8218文字はコンマのように見えないことに注意してください。これはあなたのケースであれば、私はRFC 4128あたりの二重引用符でコンマ(またはセミコロン)でフィールドを囲むお勧めします:https://tools.ietf.org/html/rfc4180


0

私は通常、コンマや特殊文字を含めることができるフィールドをURLエンコードします。そして、それが任意のビジュアルメディアで使用/表示されているときにデコードします。

(カンマは%2Cになります)

すべての言語には、文字列をURLエンコードおよびデコードするメソッドが必要です。

例:Java

URLEncoder.encode(myString,"UTF-8"); //to encode
URLDecoder.decode(myEncodedstring, "UTF-8"); //to decode

これは非常に一般的な解決策であり、ユーザーがcsvファイルのコンテンツを手動で表示したい状況には理想的ではないかもしれません。


0

私は通常、これをCSVファイル解析ルーチンで行います。「line」変数がCSVファイル内の1行であり、すべての列の値が二重引用符で囲まれていると想定します。以下の2行が実行されると、「値」コレクションにCSV列が表示されます。

// The below two lines will split the columns as well as trim the DBOULE QUOTES around values but NOT within them
    string trimmedLine = line.Trim(new char[] { '\"' });
    List<string> values = trimmedLine.Split(new string[] { "\",\"" }, StringSplitOptions.None).ToList();

1
StackOverflowでコードが複数の色で表示されないのはなぜですか?4つのスペースでインデントします。
user1451111、2016


0

私が見つけた最も簡単なソリューションは、LibreOfficeが使用するものです。

  1. すべてのリテラル"
  2. 文字列を二重引用符で囲みます

Excelが使用するものを使用することもできます。

  1. すべてのリテラル"""
  2. 文字列を二重引用符で囲みます

上記のステップ2のみを実行することを推奨している他の人に注意してください。ただし、CSVのように、文字列が1つの列にしたいCSVのように、"aの後にが続く行では機能しません。,hello",world

"hello",world"

二つの列と行として解釈される:hello及びworld"


1
標準のルールでは、分割文字または引用符のいずれかを含むフィールドは引用符で囲まれ、その中の引用符は二重になっているため、問題はありません。あなたのhello",worldフィールドには、単にとして保存する必要が"hello"",world"100%正確に解析することができ、。
Nyerguds

0
    public static IEnumerable<string> LineSplitter(this string line, char 
         separator, char skip = '"')
    {
        var fieldStart = 0;
        for (var i = 0; i < line.Length; i++)
        {
            if (line[i] == separator)
            {
                yield return line.Substring(fieldStart, i - fieldStart);
                fieldStart = i + 1;
            }
            else if (i == line.Length - 1)
            {
                yield return line.Substring(fieldStart, i - fieldStart + 1);
                fieldStart = i + 1;
            }

            if (line[i] == '"')
                for (i++; i < line.Length && line[i] != skip; i++) { }
        }

        if (line[line.Length - 1] == separator)
        {
            yield return string.Empty;
        }
    }

0

私はCsvreaderライブラリーを使用しましたが、それを使用して、列の値のコンマ(、)から分解してデータを得ました。

したがって、ほとんどの列の値にカンマ(、)を含むCSVファイルデータを挿入したい場合は、以下の関数を使用できます。著者リンク=> https://gist.github.com/jaywilliams/385876

function csv_to_array($filename='', $delimiter=',')
{
    if(!file_exists($filename) || !is_readable($filename))
        return FALSE;

    $header = NULL;
    $data = array();
    if (($handle = fopen($filename, 'r')) !== FALSE)
    {
        while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE)
        {
            if(!$header)
                $header = $row;
            else
                $data[] = array_combine($header, $row);
        }
        fclose($handle);
    }
    return $data;
}

0

papaParseライブラリーを使用してCSVファイルを解析し、キーと値のペア(キー/ヘッダー/ CSVファイルと値の最初の行)を用意しました。

ここに私が使用する例があります:

https://codesandbox.io/embed/llqmrp96pm

CSV解析デモを行うために、dummy.csvファイルが含まれています。

任意の言語で書かれたアプリで複製するのは簡単でシンプルですが、reactJS内で使用しました。


0

例は、カンマが.csvファイルでどのように表示されるかを示すのに役立ちます。次のように単純なテキストファイルを作成します。

このテキストファイルを拡張子 ".csv"のテキストファイルとして保存し、Windows 10のExcel 2000で開きます。

aa、bb、cc、d; d「スプレッドシートプレゼンテーションでは、下の行は上の行のように見えるはずですが、下の行はセミコロンの代わりにカンマの代わりに表示されます。」aa、bb、cc、 "d、d"、これはExcelでも機能します

aa、bb、cc、 "d、d"、これはExcel 2000でも機能しますaa、bb、cc、 "d、d"、これはExcel 2000でも機能しますaa、bb、cc、 "d、d"、これは機能しますExcel 2000でも

aa、bb、cc、 "d、d"、最初の引用の前のスペースが原因でExcel 2000で失敗するaa、bb、cc、 "d、d"、最初の引用の前のスペースが原因でExcel 2000で失敗するaa、bb、cc、 "d、d"、最初の引用符の下のスペースが原因でExcel 2000でこれが失敗する

aa、bb、cc、 "d、d"、これは、2番目の引用の前後にスペースがあっても、Excel 2000でも機能します。aa、bb、cc、 "d、d"、これは、2番目の引用の前後にスペースがあっても、Excel 2000でも機能します。aa、bb、cc、 "d、d"、これは、2番目の引用符の前後にスペースがあっても、Excel 2000でも機能します。

ルール:.csvファイルのセル(フィールド)にコンマを表示する場合:「フィールドの開始と終了には二重引用符を使用しますが、最初の引用符の前の空白は避けます」


-1

この問題の最も簡単な解決策は、お客様にcsvをExcelで開いてから、Ctrl + Rを押して、すべてのカンマを任意の識別子に置き換えることです。これは顧客にとって非常に簡単であり、選択した区切り文字を読み取るためにコードを1回変更するだけで済みます。


誰が彼らがExcelを持っていると言いますか?実際、誰がアップロードをしている人間でさえ言うのか...
bytedev

-3

フィールドを区切るには、タブ文字(\ t)を使用します。


4
-1誰かが自分の値のタブを使用するまでは素晴らしいです。それから、質問をしている人が持っている問題にあなたの権利が戻ってきます。1つの区切り文字を別の文字に交換しても問題は解決されません。
bytedev

ナンセンス。データ入力にタブを入力することはできません。ほとんどのフォームでは、データエントリポイントを次のフィールドに移動するだけです。
Pierre

6
「人々は彼らのデータ入力でタブを入力することができません」....あなたは本気ですか?A)もちろん、人は入力フィールドにタブを置くことができますB)データのGUIであると誰が言ったのですか?C)データを入力している人間でさえ誰が言うのですか?
bytedev 2016
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.