【问题标题】:How to parse a CSV without capturing erroneous delimiters?如何在不捕获错误分隔符的情况下解析 CSV?
【发布时间】:2016-07-04 12:34:17
【问题描述】:

在我的程序中,我得到了一个巨大的 csv String,我需要将其解析成一个数据表。数据是这样的:

["Email Address","First Name","Last Name","Phone #","Notes","Group"]
["email@email.com","First","Last","555-555-5555","Note",5]
["email2@email.com","First2","Last2","555-555-5555",null,3]

(要在这个上做一个MVCE,你可以用这个:)

String text = "[\"Email Address\",\"First Name\",\"Last Name\",\"Phone #\",\"Notes\",\"Group\"]\n" +
    "[\"email@email.com\",\"First\",\"Last\",\"555-555-5555\",\"Note\",5]\n" +
    "[\"email2@email.com\",\"First2\",\"Last2\",\"555-555-5555\",null,3]";

第一行是表头,后面的行是值。每行都包含在[] 中,并且值以逗号分隔。

我需要:

  1. 分隔行
  2. 分隔每个值

对于#1,我认为这种方法很好:

Pattern eachLinePattern = Pattern.compile("\\[.*\\][\r\n]+");
Matcher matcher = eachLinePattern.matcher(text);
while (matcher.find()) {
    String line = matcher.group().trim();
}

此正则表达式将捕获 [] 之间的所有内容 (.*),后跟 \n\r,这足以捕获所有行(这听起来像一个声明,但这是一个问题。我是否错过了这方面的潜在陷阱?)

对于#2,这是我遇到困难的地方。有些项目是字符串(""),有些不是(null、#s 等)。

我的第一个想法是使用逗号作为分隔符来创建.split()

Pattern eachLinePattern = Pattern.compile("\\[.*\\][\r\n]+");
Matcher matcher = eachLinePattern.matcher(text);
while (matcher.find()) {
    String line = matcher.group().trim();
    String[] eachItem = line.split(",");
    for(String item : eachItem)
        System.out.println(item);
}

但是,这也有明显的副作用,即在数据中捕获逗号。那么,如何确保数据中的逗号不会被捕获为错误的分隔符?

【问题讨论】:

  • 不确定如果您的值分隔符也可能在值本身中找到,您可以做什么。也许尝试使用"," 作为分隔符并从第一个元素中删除开头" 并从最后一个元素中删除" - 只是一个想法 - update 仍然不确定如何处理null 值,但这可能是一个预处理步骤(即用空字符串替换 null)
  • @ochi,我无法控制 CSV 格式。 :/ 要么解析它,要么死。
  • 知道了。所以,在你之前 .split()"" 替换 null (假设 null 是在这种情况下插入的单词)或在两个连续的逗号内插入一个空字符串......等等。
  • @ochi,虽然没有解决数字的问题。数据集中的非字符串值不仅仅是nulls。
  • true... 数据集是否始终采用相同的格式?非字符串值总是“行”的最后一个元素吗? - 一些标准行分隔符失败,您可能需要做出一些假设

标签: java regex csv


【解决方案1】:

您需要自己做吗? Apache Commons CSV 库是我用来解析 CSV 文件的一种选择(有 others)。在解析分隔文本时存在数量惊人的极端情况,而其他人已经比您做得更好了。

【讨论】:

  • 我愿意尝试新的 API。以前从来不需要做任何复杂的解析(如果我什至称 -this- complex 的话,idk )。我去看看
猜你喜欢
  • 2011-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-03
相关资源
最近更新 更多