区切りファイルを処理する最良の方法


16

したがって、通常、CSVファイルでは、フィールドと行の区切り文字としてカンマと戻り文字が使用されます。

これにより、これらの両方の文字を含む可能性のあるテキストで明らかな問題が発生します。

明らかにオプションがありますが(エスケープ)、これをどのように処理しますか?別の文字を使用してください-パイプまたはチルダ?それらをエスケープしますか?区切りファイルを使用しないでください。結局のところ、2010年であり、現在XMLがありますか?

問題が見当たらないまともなチャンスを求めて、少なくとも努力をしています。

(明らかに、これはより堅固なものではなく、好奇心からの質問です-私は何度も何度もデータを使って遊んでいますが、常にそれを回しましたが、通常は少し、よく、汚い感じがします他の人の経験は何だろうと思いました)。


CSVの使用については慎重に検討してください-扱いやすく(一般的なエスケープルールの回答を参照)、本来のように相互運用性はほとんどありません-独自のプログラムと通信しているだけの場合は問題ありませんが、別のプログラムは異なるエスケープ規則に従うため、他の場所にインポートしたい場合は少し奇妙になります。
マイケルコーネ

@Michael-もちろん。しかし問題は非常に偏在しているため、非常に魅力的なオプションである場合がほとんど常にあることであり、多くの古いシステムの場合はそれが唯一のオプションです。
ジョンホプキンス

成熟したライブラリは、文字で区切られたファイルを読み書きするための多くの言語(確かに一般的なもの)に存在します。ほとんどの状況を処理します。独自のCSVパーサーを記述することは、一般的なアンチパターンのようです。
クエンティン

回答:


13

ウィキペディアによると:

コンマが埋め込まれたフィールドは、二重引用符で囲む必要があります。

そしてさらに:

二重引用符が埋め込まれたフィールドは二重引用符で囲まれている必要があり、埋め込まれた二重引用符はそれぞれ二重引用符のペアで表されている必要があります。

誰がそれを発明したのかはわかりませんが、それは事実上、あなたが逃げなければならないことを示しています。それは唯一の固い解決策です。それ以外はすべて、ダクトテープの上にあるダクトテープです。今のところは動作する可能性がありますが、最終的には例外の例外に例外が必要な場合にぶつかります。単純なエスケープ文字ソリューションよりもはるかに複雑です。

CSV作成者は最初に二重引用符で囲まれた特別な構文を考え出すことでコンマのエスケープを避けようとしましたが、カンマを保存できましたが、誰かが二重引用符の文字も保存したかったので、その時点でエスケープする必要がありました-おかしなエスケープ文字としての二重引用符。そもそも彼らが適切に脱出することを決めていたら、構文はより簡単になります。


3
何があり、何が..しばしば異なる:)
ティムポスト

解決策は大丈夫だと思います。単純なデータの場合、CSVは、トレースはBASICに戻る『"と』その後、necesaryで引用、およびエスケープ複雑なデータのために、罰金を動作します。
Ernelli

1
@Ernelli:考えてみると、実際には人間の可読性とシンプルさの間の合理的な妥協案かもしれません。エスケープの問題は、コンピューターが構文解析するのは簡単なことですが、人間にとっては見苦しいことです。したがって、まれなケース(「二重引用符が埋め込まれたフィールド」)のみのエスケープを予約すると、通常は非常に人間が読めるように見える出力が生成されます。これは、フィールド名のコンマがフィールド名の二重引用符よりも頻繁に使用されることを想定した場合の良い解決策です。
ジョナスプラッカ

2

私はあなたがこのようなものを持っていると仮定しています:

Foo,Baz,,,"Foo,Baz"

区切り文字を含む文字列が引用符で囲まれていないかエスケープされていない場合、ファイルを解析する実際の信頼できる方法はありません。

ただし、次のような結論を解析して引き出すためにデータを調べることができます。

  • カンマ区切りのフロートは文字列として扱う必要があります
  • この前後の行に含まれる区切り文字が少ない場合、この行の解析をスキップしてログに記録します
  • 「のような」を扱う

そのようなものを処理するためにパーサーを作成する必要がありますが、複雑にする必要はありません。

私の経験では、Excelのようなものから大量のダンプをインポートすると、常に戻って奇妙なものを確認する必要があります。あなたの課題は、あなたのプログラム与えることであるだけで、それは狂気の挿入をしないように、データに関する十分な常識を。次に、記録された内容を確認し、洗浄/すすぎ/繰り返します。

私はかつて、すべてのUbuntuワークステーションを使用する小さな会社の内部FAQを処理しました。FAQの一部は「シェルショートカット」を提供し、パイプで区切られたものになりました。まあ、答えは通常パイプで区切られ(つまりgrep foo |何か)、引用もエスケープもされませんでした。私はその痛みを感じます:)


2

ある時点までCSVに問題はありません

CSVは、形式を変更する可能性が低く、受信者パーサーに多くの驚きをもたらさない、厳密に定義されたデータに対してうまく機能します。

大きな落とし穴の便利なリストを次に示します。

  1. 「」内の「」のエスケープ(フィールドにはフィールド区切り文字が含まれます)
  2. CRLFを含む「」(フィールドには行区切り文字が含まれます)
  3. Unicode(基礎となるテキスト形式では不十分な場合があります)
  4. 異なるOSの異なるラインターミネータ(CRまたはCRLFまたはLFまたはNUL)
  5. インラインコメント(#、//、-、;などのプレフィックスが付いた行)
  6. バージョン管理(ファイルの最新バージョンには、多少のフィールドが含まれています)
  7. NULLと空のデータの区別(、 ""、は空ですが、,,は空ですか?)

フィールドの解析方法を記述するメタデータヘッダーを使用してこれにアプローチできますが、XMLを使用することもできます。このようなフリーフォームのCSVの混乱が原因で発明されました。XMLのアプローチは、一見単純な問題になる可能性があるため、あまりにも重いようです。

人気のある代替手段は、「奇妙な文字区切り文字」戦略です。これは、上記のエスケープの問題の多くを回避します。(パイプ)フィールド区切り用の文字、およびレコード終了用のCRLF。これは、フィールドカウンターを使用しない限り、複数行フィールドの問題を回避できませんが、人間にとっては適切にフォーマットされた行を取得します。

全体として、この種のファイルを処理する簡単な方法を探しているだけであれば、Javaの世界では、単にOpenCSVを投げることができます。そのようにして、すべての問題を確立されたフレームワークに抽象化します。


2

CSVは多くの状況で依然として有効な形式です。特に、顧客がアプリケーションにインポートする必要のあるデータを記述する最も簡単な方法である必要があるためです。おそらく非常に冗長であり、これらの「怖い」山括弧をすべて持っているため、XMLを扱うことを好む顧客はほとんどいません。合意されたキャラクターで区切られたアイテムの単純なリストに頭を包み、フィールドのコンテンツに同じキャラクターが許可されないことに同意することは、彼らにとって非常に簡単です。

ただし、入力を正しく処理し、無効な文字を使用する状況を確認する必要があります。CSV解析のニーズにFileHelpersを使用し始めました。


1

私は通常、標準に固執し、それらをエスケープします。ほとんどのプログラミング言語では、優れた組み込みサポートまたは利用可能な優れたライブラリがあります。

どのフォーマットが使用されるかによりますが、CSVは単純なデータフォーマット構造を交換するための合理的なフォーマットです。


0

CSVを忘れて、JSONを使用します。書きやすく、解析しやすい。XMLは2005年です。


6
あなたはJSON形式の一部(、のような{か)のキャラクターを使用したい場合は、同じ問題を抱えている
Salandur

Salandur:まったく違います!脱出する正確なルールがあります!しかし{と、エスケープする必要さえありません。なぜなら、内部は文字列であり、あいまいではないからです!
user281377

1
よく、しかし、「JSONにエクスポート」機能を備えているExcelを覚えていません:)より奇妙なものを解析する必要がある場合があります。
ティムポスト

1
また、JSONは、同じ形状の100万個のオブジェクトを渡すのに非常に優れています。えっ、ちょっと待って。
フランクシェラー

1
JSONは、この質問に関してCSVの改善を提供せず、多くのアプリケーションとの相互運用性に決定的に欠けています(前述したように、Office、SQL DBなどからインポートまたはエクスポートできません)。JSONは、内部の軽量なクライアント側の操作には適していますが、アプリケーション間でデータを渡すにはXMLの方がはるかに優れています。
ダンディプロ

0

通常、私がしているのは、CSVファイルではなくTSV(タブ区切り値)を取得し、ファイルをEmacsに取り込み、使用されていないいくつかの珍しい文字を確認することです(通常、ここでは$が適切な選択です)。そして、すべてのタブを$に変換します。

そこから、GNU AWKはフィールド区切り文字として$を使用するように指示され、ボブはあなたのおじです。

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