10

如果将 CSV 重新定义为“字符分隔值”,即使用任何单个字符(但通常是任何非字母数字符号)作为分隔符而不仅仅是逗号的数据,那么自动检测文件实际上是 CSV的可靠方法是什么?

本质上,使用这个(重新)定义,CSV = DSV(“分隔符分隔值”),例如,在这篇维基百科文章中讨论过,而“逗号分隔值”格式在RFC 4180中定义。

更具体地说,是否有一种方法可以统计推断数据具有某种“固定”长度,即“可能的 CSV”?仅仅计算分隔符的数量并不总是有效的,因为 CSV 文件的每条记录具有可变数量的字段(即,与 RFC 4180 要求相反的记录,在同一文件中没有相同数量的字段)。

CSV 识别似乎是一个特别具有挑战性的问题,特别是如果检测不能基于文件扩展名(例如,当读取一个无论如何都没有此类信息的流时)。

正确(“完整”)的自动检测需要至少 4 个可靠的决策:

  1. 检测文件实际上是 CSV
  2. 检测标题的存在
  3. 检测实际的分隔符
  4. 检测特殊字符(例如,引号)

由于其他数据集的相似性(例如,使用逗号的自由文本),完全自动检测似乎没有单一的解决方案,特别是对于可变长度记录、单引号或双引号字段或多行记录等极端情况。

因此,最好的方法似乎是伸缩检测,其中在应用 CSV 检测规则之前检查也可以归类为 CSV 的格式(例如,像 Apache CLF 这样的日志文件格式)。

甚至像 Excel 这样的商业应用程序似乎也依赖文件扩展名 (.csv) 来决定 (1),这显然不是自动检测,尽管如果应用程序被告知数据是 CSV,问题就会大大简化。

以下是一些很好的相关文章,讨论了 (2) 和 (3) 的启发式方法:

(4) 的检测,即引号的类型,可以基于处理文件中的几行并查找相应的值(例如,每行偶数个 ' 或 " 表示单引号或双引号)。这样的处理可以通过初始化现有的 CSV 解析器(例如,OpenCSV)来完成,该解析器将妥善处理 CSV 行分隔(例如,多行事件)。

但是(1),即首先确定数据是 CSV 呢?

数据挖掘可以帮助做出这个决定吗?

4

2 回答 2

6

如果您无法限制用作分隔符的内容,则可以使用蛮力。

您可以遍历引号字符、列分隔符和记录分隔符的所有可能组合(ASCII 为 256 * 255 * 254 = 16581120)。

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

删除所有引用的列,这可以通过 RegEx 替换来完成。

//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/empty 或有效(int、float、date)

可以使用的 CSV 数据(行、列)越多,您从该方法中提取的信心就越大。

我认为这个问题有点愚蠢/过于笼统,如果您有一系列未知数据,您肯定会首先检查所有“低悬的果实”。二进制格式通常具有相当不同的标头签名,然后是 XML 和 JSON 用于易于检测的文本格式。

于 2011-12-19T20:03:52.003 回答
1

总会有看起来像 CSV 的非 CSV 文件,反之亦然。例如,有 frankc 在您引用的 Java 链接中发布的病态(但完全有效)CSV 文件:

Name
Jim
Tom
Bill

我认为,最好的方法是对文件为 CSV 的可能性进行某种启发式估计。我能想到的一些启发式方法是:

  1. 每一行都有一个候选分隔符(或者,如果您愿意,每一行都有一个标记)。
  2. 给定一个候选分隔符,大多数(但不一定是所有)行具有相同数量的字段。
  3. 看起来可能是标题的第一行的存在增加了文件包含 CSV 数据的可能性。

人们可能会想出其他启发式方法。然后,该方法将是开发基于这些的评分算法。下一步是对已知 CSV 和非 CSV 文件的集合进行评分。如果有足够清晰的分离,那么评分可能被认为是有用的,并且分数应该告诉您如何设置检测阈值。

于 2011-12-19T19:38:08.083 回答