解析CSV文件

3
我们与另一个系统进行集成,依赖于来回传递CSV文件(非常老派)。一般的结构如下:
ID, Name, PhoneNumber, comments, fathersname
1, tom, 555-1234, just some random text, bill
2, jill smith, 555-4234, other random text, richard

有时我们会看到这样的情况:

3, jacked up, 999-1231, here  
be dragons  
amongst us, ted

我关注的主要问题是当换行符(\n)作为记录结束符时,在记录中间发现该符号的检测问题。

有没有什么方法可以对此进行预处理以可靠地解决它?

请注意,我们对其他系统的输出 没有任何控制权


有很多CSV阅读器可供选择...我过去曾经成功使用过这个。它非常快速。http://www.codeproject.com/Articles/9258/A-Fast-CSV-Reader您可以设置规则并进行微调。 - user195488
3
找到编写生成无效格式代码的人并惩罚他们,然后只需让您的代码 throw new FormatException();。我认为大多数格式化程序将无法处理此问题,除非在字段周围加上引号;您需要自己编写。 - Servy
我想你可以在新行上计算未转义的,字符数,如果为0,则实际上不是新记录。 - Magnus
将标准列表发送给他们,http://www.creativyst.com/Doc/Articles/CSV/CSV01.htm#EmbedBRs,其中规定字段可以嵌入换行符,但必须用引号括起来。可以查找一些可能已经处理此问题的库,http://www.codeproject.com/Articles/25133/LINQ-to-CSV-library 可能是一个选择。 - Luke Hutton
3个回答

1

所以你应该能够做到类似于这样的事情:

for (int i = 0; i < lines.Count; i++)
{
    var fields = lines[i].Split(',').ToList();
    while (fields.Count < numFields)//here be dragons amonst us
    {
        i++;//include next line in this line
        //check to make sure we haven't run out of lines.

        //combine end of previous field with start of the next one, 
        //and add the line break back in.
        var innerFields = lines[i].Split(',');
        fields[fields.Count - 1] += "\n" + innerFields[0];

        fields.AddRange(innerFields.Skip(1));
    }

    //we now know we have a "real" full line
    processFields(fields);
}

为简单起见,我假设所有行在开始时都已被读取;我认为您可以轻松地更改它以惰性获取每一行。


我喜欢这个。会试一下。 - NotMe

0
首先,我建议使用一个工具来管理读写CSV文件,我使用FileHelpers库,这非常好。
你可以基本上输入记录,它会为你做所有的验证等等。值得一试。
对于你的问题,也许你可以在文件上进行一些预处理,并使用正则表达式将任何换行符替换为空格?
我做类似的事情(不是与文件一起),请尝试。
line.Replace(Environment.NewLine, " ");

使用FileHelpers,您可以编写自定义转换器来在处理过程中执行此操作,或者钩入BeforeRead事件。

我们已经在使用FileHelpers了。然而,它会在不符合规范的行上出错,所以我们将其设置为忽略这些行并继续执行。如果您有关于编写自定义转换器来处理它的详细信息,我很感兴趣... - NotMe

0

首先,让我说一下,你示例中的CSV文件是无效的。如果字符串内出现换行符,则应使用双引号字符进行包装。

现在来回答问题-为了解析这个无效的csv格式,您必须做出几个假设。在这种情况下,我做出了两个假设:1)ID列必须是数字2)注释字段不能包含数字。

基于这些假设,您可以检查换行符后的第一个字符。如果它是数字,则假定它是新记录。如果不是,则应将其视为注释字段的继续值。

我不知道第二个假设是否有效,如果无效,则可以增强逻辑,以涵盖系统的业务规则。

祝你好运!


你说得完全正确,它是无效的。然而,生产这个垃圾的大型企业已经承诺修复它三年了,所以我不抱有太大希望。不幸的是,我们不能保证1,评论字段很可能以数字开头。 - NotMe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接