gpt4 book ai didi

java - Java 中的 CSV 自动检测

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:58:46 26 4
gpt4 key购买 nike

如果 CSV 被重新定义为表示“字符分隔值”,即使用任何单个字符(但通常是任何非字母数字符号)作为分隔符而不仅仅是逗号?

本质上,通过这个(重新)定义,CSV = DSV(“定界符分隔值”),例如,在此 Wikipedia article 中进行了讨论,而“逗号分隔值”格式在 RFC 4180 中定义.

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

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

正确(“完整”)自动检测需要至少 4 个决定才能可靠地做出:

  1. 检测文件实际上是 CSV
  2. 检测 header 的存在
  3. 检测实际的分隔符
  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

删除所有引用的列,这可以通过 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 数据(行、列)越多,您可以从该方法中提取的信心就越大。

我认为这个问题有点愚蠢/过于笼统,如果您有一系列未知数据,您肯定希望首先检查所有“唾手可得的果实”。二进制格式通常具有截然不同的 header 签名,然后是易于检测的文本格式的 XML 和 JSON。

关于java - Java 中的 CSV 自动检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8566321/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com