如果CSV被重新定义为“字符分隔值”,即使用任何单个字符(但通常使用任何非字母数字符号)作为分隔符而不是逗号,那么自动检测文件实际上是CSV值的可靠方法是什么?
本质上,在这个(Re)定义中,CSV = DSV (“分隔符-分隔值”),例如在这个维基百科文章中讨论过,而“逗号分隔值”格式是在RFC 4180中定义的。
更具体地说,是否有一种方法来统计推断数据是“固定”长度的,意思是“可能的CSV"?仅仅计算分隔符的数量并不总是有效的,因为每个记录都有带有可变字段数的CSV文件(也就是说,与RFC 4180任务相反的记录,在同一文件中没有相同数量的字段)。
CSV识别似乎是一个特别具有挑战性的问题,特别是如果检测不能基于文件扩展名(例如,当读取没有此类信息的流时)。
正确(“完全”)自动检测至少需要4个决策()才能可靠地做出:
由于其他数据集(例如,使用逗号的免费文本)的相似之处,完全自动检测似乎没有单一的解决方案,特别是对于诸如可变长度记录、单行或双引号字段或多行记录等角落情况。
因此,最好的方法似乎是伸缩检测,其中也可以分类为CSV的格式(例如,日志文件格式,如Apache )将在应用CSV检测规则之前进行检查。
即使像Excel这样的商业应用程序似乎也依赖于文件扩展名(.csv)来决定(1),这显然不是自动检测,尽管如果应用程序被告知数据是CSV,问题就大大简化了。
下面是一些很好的相关文章,讨论(2)和(3)的启发式:
(4)是引号的类型,它的检测可以基于从文件中处理几行并查找相应的值(例如,每一行的偶数‘或“表示单引号或双引号)。这种处理可以通过初始化现有的CSV解析器(例如OpenCSV)来完成,该解析器将适当地处理CSV行分隔(例如,多行事件)。
但是(1)呢,即首先确定数据是CSV?
数据挖掘对此决策有帮助吗?
发布于 2011-12-19 20:03:52
如果你不能限制什么使用作为分隔符,那么你可以使用蛮力。
您可以遍历引号字符、列分隔符和记录分隔符的所有可能组合(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如果列数不匹配,则尝试另一个行、列和引号字符的组合
编辑
在您对分隔符有信心并检查列类型的一致性之后,实际上解析了数据,这可能是一个有用的额外步骤。
使用的CSV数据(行、列)越多,就越有信心从该方法中提取.。
我认为这个问题有点愚蠢/过于笼统,如果你有一系列未知的数据,你肯定会首先检查所有的“低挂水果”。二进制格式通常具有相当不同的头签名,然后是XML和JSON,用于易于检测的文本格式。
发布于 2011-12-19 19:38:08
总是会有类似CSV的非CSV文件,反之亦然。例如,frankc在您引用的Java链接中发布的CSV文件是病态的(但非常有效):
Name
Jim
Tom
Bill我认为,最好的方法是对文件是CSV的可能性进行某种启发式的估计。一些我能想到的启发式方法是:
人们可能会想出其他的启发式方法。然后,方法是在此基础上开发一种评分算法。下一步是收集已知的CSV和非CSV文件。如果有一个明确-足够的分离,那么得分可以被认为是有用的,分数应该告诉你如何设置一个检测阈值。
https://stackoverflow.com/questions/8566321
复制相似问题