CSV字符串处理

创建CSV字符串的典型方法(伪代码):

  • 创建一个CSV容器对象(如C#中的StringBuilder)。
  • 循环遍历要添加的字符串,并在每个字符后添加逗号。
  • 循环后,删除最后多余的逗号。
  • 代码示例:

    public string ReturnAsCSV(ContactList contactList)
    {
        StringBuilder sb = new StringBuilder();
        foreach (Contact c in contactList)
        {
            sb.Append(c.Name + ",");
        }
    
        sb.Remove(sb.Length - 1, 1);
        //sb.Replace(",", "", sb.Length - 1, 1)
    
        return sb.ToString();
    }
    

    我喜欢通过检查容器是否为空来添加逗号的想法,但这并不意味着需要更多处理,因为它需要在每次出现时检查字符串的长度?

    我觉得应该有一个更容易/更清洁/更有效的方法去除最后一个逗号。 有任何想法吗?


    你可以使用LINQ to Objects:

    string [] strings = contactList.Select(c => c.Name).ToArray();
    string csv = string.Join(",", strings);
    

    显然这可以全部在一行中完成,但是在两个方面它会更清晰一些。


    您的代码不完全符合完整的CSV格式。 如果您只是从没有逗号,前导/尾随空格,制表符,换行符或引号的数据生成CSV,则应该没问题。 但是,在大多数现实世界的数据交换场景中,您确实需要全面的资源。

    为了生成正确的CSV,你可以使用这个:

    public static String EncodeCsvLine(params String[] fields)
    {
        StringBuilder line = new StringBuilder();
    
        for (int i = 0; i < fields.Length; i++)
        {
            if (i > 0)
            {
                line.Append(DelimiterChar);
            }
    
            String csvField = EncodeCsvField(fields[i]);
            line.Append(csvField);
        }
    
        return line.ToString();
    }
    
    static String EncodeCsvField(String field)
    {
        StringBuilder sb = new StringBuilder();
        sb.Append(field);
    
        // Some fields with special characters must be embedded in double quotes
        bool embedInQuotes = false;
    
        // Embed in quotes to preserve leading/tralining whitespace
        if (sb.Length > 0 && 
            (sb[0] == ' ' || 
             sb[0] == 't' ||
             sb[sb.Length-1] == ' ' || 
             sb[sb.Length-1] == 't' ))
        {
            embedInQuotes = true;
        }
    
        for (int i = 0; i < sb.Length; i++)
        {
            // Embed in quotes to preserve: commas, line-breaks etc.
            if (sb[i] == DelimiterChar || 
                sb[i]=='r' || 
                sb[i]=='n' || 
                sb[i] == '"') 
            { 
                embedInQuotes = true;
                break;
            }
        }
    
        // If the field itself has quotes, they must each be represented 
        // by a pair of consecutive quotes.
        sb.Replace(""", """");
    
        String rv = sb.ToString();
    
        if (embedInQuotes)
        {
            rv = """ + rv + """;
        }
    
        return rv;
    }
    

    可能不是世界上最高效的代码,但它已经过测试。 与快速示例代码相比,真实世界很糟糕:)


    为什么不使用其中的一个开源CSV库?

    我知道这听起来像是一件过于简单的事情,但正如您可以通过评论和代码片段所了解的那样,它们不仅仅是满足眼球。 除了处理完整的CSV合规性,您最终还是希望处理读取和写入CSV ......并且您可能需要文件操作。

    我之前在其中一个项目中使用过Open CSV(但还有很多其他项可供选择)。 这当然使我的生活更轻松。 ;)

    链接地址: http://www.djcxy.com/p/51317.html

    上一篇: CSV string handling

    下一篇: Linq : filter duplicated line without taking account a column