PNS*_*PNS 10 java csv data-mining autodiscovery
如果CSV被重新定义为"字符分隔值",即使用任何单个字符(但通常是任何非字母数字符号)作为分隔符而不仅仅是逗号的数据,那么自动检测文件实际上是CSV的可靠方法是什么??
本质上,使用此(重新)定义,CSV = DSV("分隔符 - 分隔值"),例如,在本维基百科文章中讨论,而"逗号分隔值"格式在RFC 4180中定义.
更具体地说,是否存在一种统计推断数据具有某种"固定"长度的方法,意味着"可能的CSV"?仅计算分隔符的数量并不总是有效,因为每个记录都有可变数量字段的 CSV文件(即,与RFC 4180要求相反的记录,在同一文件中没有相同数量的字段).
CSV识别似乎是一个特别具有挑战性的问题,特别是如果检测不能基于文件扩展名(例如,当读取无论如何都没有这种信息的流时).
正确("完整")自动检测需要至少4个可靠的决策:
由于其他数据集(例如,使用逗号的自由文本)的相似性,完全自动检测似乎没有单一的解决方案,特别是对于诸如可变长度记录,单引号或双引号字段或多行记录的转角情况.
因此,最佳方法似乎是望远镜检测,其中在应用CSV检测规则之前检查也可以归类为CSV的格式(例如,像Apache CLF这样的日志文件格式).
甚至像Excel这样的商业应用程序似乎依赖于文件扩展名(.csv)来决定(1),这显然不是自动检测,尽管如果应用程序被告知数据是CSV,问题会大大简化.
以下是一些讨论(2)和(3)的启发式的好相关文章:
(4)(引号的类型)的检测可以基于处理来自文件的几行并查找相应的值(例如,每行的偶数'或'将表示单引号或双引号).可以通过初始化现有的CSV解析器(例如,OpenCSV)来完成,该解析器将适当地关注CSV行分离(例如,多行事件).
但是(1),即首先确定数据是CSV呢?
莫非数据挖掘这一决定帮助吗?
如果你不能限制用作分隔符的什么,那么你可以使用暴力.
您可以遍历引号字符,列分隔符和记录分隔符的所有可能组合(对于ASCII,256*255*254 = 16581120).
id,text,date
1,"Bob says, ""hi
..."", with a sigh",1/1/2012
Run Code Online (Sandbox Code Playgroud)
删除所有引用的列,这可以通过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
Run Code Online (Sandbox Code Playgroud)
拆分记录分隔符
["id,text,date", "1,,1/1/2012"]
Run Code Online (Sandbox Code Playgroud)
拆分列分隔符上的记录
[ ["id", "text", "date"], ["1", "", "1/1/2012"] ]
Run Code Online (Sandbox Code Playgroud)
如果每条记录的列数匹配,则您有一些CSV置信度.
3 == 3
Run Code Online (Sandbox Code Playgroud)
如果列数不匹配,请尝试另一种行,列和引号字符组合
编辑
实际上,在对分隔符有信心并检查列类型一致性之后解析数据可能是一个有用的额外步骤
可以使用的CSV数据(行,列)越多,您可以从此方法中提取的信心越大.
我认为这个问题有点愚蠢/过于笼统,如果你有一堆未知数据,你肯定要首先检查所有"低悬的水果".二进制格式通常具有相当不同的标题签名,然后有易于检测的文本格式的XML和JSON.