10

CSV が「文字区切り値」を意味するように再定義された場合、ファイルが実際に CSV であることを自動検出する信頼できる方法は何でしょう。?

本質的に、この (再) 定義では、CSV = DSV ("区切り記号で区切られた値") が、たとえばこのウィキペディアの記事で説明されていますが、"カンマで区切られた値" 形式はRFC 4180で定義されています。

より具体的には、データが何らかの形で「固定」長さ、つまり「可能なCSV」であることを統計的に控除する方法はありますか? 区切り文字の数を数えるだけでは、レコードごとに可変数のフィールドを持つ CSV ファイルがあるため、常に機能するとは限りません(つまり、RFC 4180 の義務とは反対に、同じファイル全体で同じ数のフィールドを持たないレコード)。

CSV の認識は、特にファイル拡張子に基づいて検出できない場合 (たとえば、そのような情報を持たないストリームを読み取る場合)、特に困難な問題のようです。

適切な (「完全な」)自動検出を確実に行うには、少なくとも 4 つの決定が必要です。

  1. ファイルが実際に CSV であることの検出
  2. ヘッダーの存在の検出
  3. 実際の区切り文字の検出
  4. 特殊文字 (引用符など) の検出

特に可変長レコード、一重引用符または二重引用符で囲まれたフィールド、または複数行のレコードなどのコーナー ケースでは、他のデータセット (コンマを使用するフリー テキストなど) と類似しているため、完全な自動検出には単一のソリューションはないようです。

そのため、CSV 検出ルールを適用する前に、CSV としても分類できる形式 (たとえば、Apache CLF のようなログ ファイル形式) を検査するテレスコピック検出が最善のアプローチのようです。

Excel のような商用アプリケーションでさえ、(1) を決定するためにファイル拡張子 (.csv) に依存しているように見えますが、これは明らかに自動検出ではありませんが、データが CSV であるとアプリケーションに通知されれば問題は大幅に単純化されます。

(2) と (3) のヒューリスティックについて説明している関連記事を次に示します。

引用符のタイプである (4) の検出は、ファイルから数行を処理し、対応する値を探すことに基づいています (たとえば、行ごとに偶数の ' または " は、一重引用符または二重引用符を意味します)。これは、CSV の行分離 (複数行イベントなど) を適切に処理する既存の CSV パーサー ( OpenCSV など)を初期化することで実行できます。

しかし、(1)、つまりそもそもデータが CSV であると判断する場合はどうでしょうか。

データ マイニングはこの決定に役立つでしょうか?

4

2 に答える 2

6

区切り文字として使用するものを制限できない場合は、ブルートフォースを使用できます。

引用符、列区切り文字、およびレコード区切り文字 (ASCII の場合は 256 * 255 * 254 = 16581120) のすべての可能な組み合わせを反復処理できます。

id,text,date
1,"Bob says, ""hi
..."", with a sigh",1/1/2012

引用符で囲まれたすべての列を削除します。これは、正規表現の置換で行うことができます。

//quick javascript example of the regex, you'd replace the quote char with whichever character your currently testing
var test='id,text,date\n1,"bob, ""hi\n..."", sigh",1/1/2011';
console.log(test.replace(/"(""|.|\n|\r)*?"/gm,""));

id,text,date
1,,1/1/2012

レコード区切り文字で分割

["id,text,date", "1,,1/1/2012"]

列区切り文字でレコードを分割する

[ ["id", "text", "date"], ["1", "", "1/1/2012"] ]

レコードあたりの列数が一致する場合は、CSV の信頼性がある程度あります。

3 == 3

列の数が一致しない場合は、行、列、および引用符の別の組み合わせを試してください

編集

区切り文字に確信が持てた後に実際にデータを解析し、列の型が均一であることを確認することは、役立つ追加のステップになる可能性があります

  • 最初の (ヘッダー?) 行の文字列のすべての列
  • 列 X は常に null/空または有効な (int、float、date) に解析されますか?

操作する CSV データ (行、列) が多いほど、この方法から抽出できる信頼性が高くなります。

この質問はばかげている/過度に一般的だと思います.不明なデータのストリームがある場合は、最初にすべての「ぶら下がっている果物」を確実に確認する必要があります. 通常、バイナリ形式にはかなり明確なヘッダー署名があり、簡単に検出できるテキスト形式には XML と JSON があります。

于 2011-12-19T20:03:52.003 に答える
1

CSV のように見える非 CSV ファイルが常に存在し、その逆もあります。たとえば、あなたが引用した Java リンクに frankc が投稿した病的な (しかし完全に有効な) CSV ファイルがあります。

Name
Jim
Tom
Bill

私ができる最善の方法は、ファイルが CSV である可能性をヒューリスティックに推定することだと思います。私が考えることができるいくつかのヒューリスティックは次のとおりです。

  1. すべての行に表示される候補区切り文字があります (または、必要に応じて、すべての行に 1 つのトークンがあります)。
  2. 区切り文字の候補が与えられた場合、ほとんどの (必ずしもすべてではない) 行に同じ数のフィールドがあります。
  3. ヘッダーのように見える最初の行があると、ファイルに CSV データが含まれている可能性が高くなります。

おそらく他のヒューリスティックを考えることができます。アプローチは、これらに基づいてスコアリング アルゴリズムを開発することです。次のステップは、既知の CSV ファイルと非 CSV ファイルのコレクションをスコアリングすることです。十分に明確な分離がある場合、スコアリングは有用であると見なされる可能性があり、スコアは検出しきい値の設定方法を示しているはずです。

于 2011-12-19T19:38:08.083 に答える