当某些元素为空时,将字符串拆分为数组

时间:2017-01-30 19:01:31

标签: c# csv split

我需要实时处理大量的csv数据,因为它是由TCP端口吐出的。这是Putty显示的一个例子:

MSG,3,1920,742,4009C5,14205994,2017/01/29,20:14:27.065,2017/01/29,20:14:27.972,,8000,,,51.26582,-0.33783,,,0,0,0,0
MSG,4,1920,742,4009C5,14205994,2017/01/29,20:14:27.065,2017/01/29,20:14:27.972,,,212.9,242.0,,,0,,,,,
MSG,1,1920,742,4009C5,14205994,2017/01/29,20:14:27.065,2017/01/29,20:14:27.972,BAW469,,,,,,,,,,,
MSG,3,1920,742,4009C5,14205994,2017/01/29,20:14:27.284,2017/01/29,20:14:27.972,,8000,,,51.26559,-0.33835,,,0,0,0,0
MSG,4,1920,742,4009C5,14205994,2017/01/29,20:14:27.284,2017/01/29,20:14:27.972,,,212.9,242.0,,,0,,,,,

我需要将每行数据以字符串()放入数组( linedata [] ),以便我可以读取和处理某些元素,但{ {1}}似乎忽略了许多空元素,结果是 linedata [20] ,例如,可能存在,也可能不存在,如果它没有,我会收到错误我试着读它。即使行中的元素20包含一个值,它也不一定是数组中的第20个元素。这没有用。

我可以弄清楚如何将 line 逐个字符解析为 linedata [] ,在适当的位置插入一个空字符串,但肯定有更好的方法吗?我错过了一些明显的东西吗?

非常感谢。也许我最好补充说我对C#很新,我过去的经验都是使用Delphi 7.我真的很想念字符表。

已编辑:抱歉,现在可以在MSDN的文档帮助下解决此问题。此代码在设置" string [] separators = {"," };&#34 ;.我最大的错误是遵循教程网站上的示例,这些示例没有给出.split方法有任何选项的任何线索。

4 个答案:

答案 0 :(得分:3)

https://msdn.microsoft.com/en-us/library/system.stringsplitoptions(v=vs.110).aspx

该链接有一个示例部分,具体看一下例1b。 Split还有一个名为 StringSplitOptions 的额外参数,可以执行此操作。

例如:

    string[] linedata = line.Split(charSeparators, StringSplitOptions.None);

    foreach (string line in linedata)
    {
        Console.Write("<{0}>", line);
    }
    Console.Write("\n\n");

查找此类信息的方法是从函数的Reference Documentation开始,并希望它有一个选项或指向类似函数的链接。

如果您还要开始验证类型,处理格式等变体......您可以升级到CSV library。如果您不需要该功能,这对于小文件来说是最简单的方法和效率。

答案 1 :(得分:2)

String.Split()的一些重载采用StringSplitOptions参数,如果使用RemoveEmptyEntries选项,它将...删除空条目。因此,您可以指定None选项:

linedata = line.Split(new [] { ',' }, StringSplitOptions.None);

或者更好的是,使用不带StringSplitOptions的重载,默认情况下将其视为None

linedata = line.Split(',');

您问题中的代码表明您正在执行此操作,但您对问题的描述表明您不是。

但是,你可能最好使用一个真正的CSV解析器,它可以处理unescaping之类的东西等。

答案 2 :(得分:0)

StringReader类提供了从字符串中读取行,字符或字符块的方法。希望这可能是线索

    string str = @"MSG,3,1920,742,4009C5,14205994,2017/01/29,20:14:27.065,2017/01/29,20:14:27.972,,8000,,,51.26582,-0.33783,,,0,0,0,0
                   MSG,4,1920,742,4009C5,14205994,2017/01/29,20:14:27.065,2017/01/29,20:14:27.972,,,212.9,242.0,,,0,,,,,
                   MSG,1,1920,742,4009C5,14205994,2017/01/29,20:14:27.065,2017/01/29,20:14:27.972,BAW469,,,,,,,,,,,
                   MSG,3,1920,742,4009C5,14205994,2017/01/29,20:14:27.284,2017/01/29,20:14:27.972,,8000,,,51.26559,-0.33835,,,0,0,0,0
                   MSG,4,1920,742,4009C5,14205994,2017/01/29,20:14:27.284,2017/01/29,20:14:27.972,,,212.9,242.0,,,0,,,,,";


    using (StringReader reader = new StringReader(str))
        do
        {
            string[] linedata = reader.ReadLine().Split(',');

        } while (reader.Read() != -1);

答案 3 :(得分:0)

虽然您应该查看String类可以在这里帮助您的各种方式,但有时需要快速而脏的“MAKE it fit”选项。在这种情况下,那就是提前滚动字符串并确保逗号之间至少有一个字符。

public static string FixIt(string s)
{
       return s.Replace(",,", ", ,");
}

你应该能够:

var lineData = FixIt(line).Split(',');

编辑:在回答下面的问题时,我不确定你的意思,但如果你的意思是在没有创建帮助方法的情况下这样做,你可以轻松地做到这一点。如果您在一行中执行此操作,则代码将更难以阅读和排除故障。我个人的规则是,如果你不得不做很多,它应该是一种方法。如果你只需要做一次,那就特别干净了。我实际上是这样做的,只需将它包装在一个为你完成所有工作的方法中。

var lineData = line.Replace(",,", ", ,").Split(',');

作为一种方法,它是:

 public static string[] GiveMeAnArray(string s)
    {
           return s.Replace(",,", ", ,").Split(',');
    }