首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >带字符串分隔符(多字符)的Java CSV解析器

带字符串分隔符(多字符)的Java CSV解析器
EN

Stack Overflow用户
提问于 2011-12-28 17:00:18
回答 3查看 20.3K关注 0票数 16

有没有Java开源库支持CSV的multi-character (长度大于1的字符串)分隔符(分隔符)?

根据定义,CSV =以逗号分隔的数据以单个字符(',')作为分隔符。然而,还有许多其他的单字符替代(例如,制表符),使得CSV代表“字符分隔值”数据(本质上是DSV:分隔符分隔值数据)。

CSV的主要Java开源库(例如,OpenCSV)几乎支持任何字符作为分隔符,但不支持字符串(多字符)分隔符。因此,对于像“|”这样的字符串分隔的数据,除了对输入进行预处理以将字符串转换为单字符分隔符之外,没有其他选择。从那时起,可以将数据解析为单字符分隔值。

因此,如果有一个本机支持字符串分隔符的库就好了,这样就不需要进行预处理了。这意味着CSV现在代表"CharSequence-Separated Values“数据。:-)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-01-01 01:17:18

这是一个好问题。这个问题对我来说并不明显,直到我看了javadocs,意识到opencsv只支持字符作为分隔符,而不是字符串……

这里有几个建议的变通方法( Groovy中的示例可以转换为java)。

忽略隐式中间字段

继续使用OpenCSV,但忽略空字段。显然,这是一种欺骗,但它可以很好地解析行为良好的数据。

代码语言:javascript
复制
    CSVParser csv = new CSVParser((char)'|')

    String[] result = csv.parseLine('J||Project report||"F, G, I"||1')

    assert result[0] == "J"
    assert result[2] == "Project report"
    assert result[4] == "F, G, I"
    assert result[6] == "1"

代码语言:javascript
复制
    CSVParser csv = new CSVParser((char)'|')

    String[] result = csv.parseLine('J|||Project report|||"F, G, I"|||1')

    assert result[0] == "J"
    assert result[3] == "Project report"
    assert result[6] == "F, G, I"
    assert result[9] == "1"

滚你自己的

使用Java String tokenizer方法。

代码语言:javascript
复制
    def result = 'J|||Project report|||"F, G, I"|||1'.tokenize('|||')

    assert result[0] == "J"
    assert result[1] == "Project report"
    assert result[2] == "\"F, G, I\""
    assert result[3] == "1"

这种方法的缺点是您无法忽略引号字符或转义分隔符。

更新

与其对数据进行预处理,改变其内容,为什么不将上述两种方法结合在一个两步的过程中:

  1. 使用“滚动您自己的”来首先验证数据。拆分每一行并证明它包含所需的字段数。
  2. 使用“忽略字段”方法来分析验证的数据,确保在知道已指定正确的字段数的情况下安全。

效率不是很高,但可能比编写自己的CSV解析器更容易:-)

票数 5
EN

Stack Overflow用户

发布于 2018-10-13 03:06:31

这些解决方案对我都不起作用,因为它们都假设您可以将整个CSV文件存储在内存中,从而允许简单的replaceAll类型操作。

我知道这很慢,但我用的是Scanner。它有许多令人惊讶的功能,并使滚动您自己的简单CSV阅读器与任何字符串,您想要的记录分隔符。它还可以让您解析非常大的CSV文件(我以前做过10 It的单个文件),因为您可以一次读取一条记录。

代码语言:javascript
复制
Scanner s = new Scanner(inputStream, "UTF-8").useDelimiter(">|\n");

我更喜欢更快的解决方案,但我还没有找到支持它的库。自2017年初以来,FasterXML已经开放了一张票来添加这一功能:https://github.com/FasterXML/jackson-dataformats-text/issues/14

票数 1
EN

Stack Overflow用户

发布于 2011-12-28 17:13:08

试试opencsv

它可以做你需要的所有事情,包括(尤其是)处理引用值中的内嵌分隔符(例如"a,b", "c"解析为["a,b", "c"])

我已经成功地使用了它,并且我喜欢它。

编辑:

因为opencsv只处理单字符分隔符,所以您可以这样解决这个问题:

代码语言:javascript
复制
String input;
char someCharNotInInput = '|';
String delimiter = "abc"; // or whatever
input.replaceAll(delimiter, someCharNotInInput);
new CSVReader(input, someCharNotInInput); // etc
// Put it back into each value read
value.replaceAll(someCharNotInInput, delimiter); // in case it's inside delimiters
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8653797

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档