【问题标题】:Converting List<string> to csv using StringBuilder使用 StringBuilder 将 List<string> 转换为 csv
【发布时间】:2014-09-07 00:06:28
【问题描述】:

我有一个使用文本文件生成的列表。我正在浏览列表并使用 StringBuilder,因此我可以使用 StringBuilder 对象创建一个 csv 文件。该文件从新记录开始时有一个 ^。当 List 返回一个包含 ^ 的字符串时,我需要能够向 stringbuilder 对象追加一个新行,但是正如您在下面的代码中看到的那样,我永远无法判断何时追加新行,我不知道不知道怎么解决。

这是我尝试过的一种方法,问题显示在 cmets 中

foreach (var a in lstData)
        {
            if (a.Contains("^"))
            {
                string strName = Regex.Replace(a, "<.*?>", string.Empty).Remove(0, 1);

                sbQ.Append(strName + ",");
            }
            else
            {
                sbQ.Append(a + ",");
            }
            if (a.Contains("^")) sbQ.AppendLine();

            // Doesn't work, always appendlines when it encounters '^'
            // should only append new line on next occurence

        }

这是另一种方式。

        string strZ;
        string strX;
        foreach (var a in lstData)
        {
            if (a.Contains("^"))
            {
                strZ = Regex.Replace(a, "<.*?>", string.Empty).Remove(0, 1);
                sbQ.Append(strZ + ",");
                strX = strZ;
            }

            if (strZ == strX)
            {
                // Causes Error : Use of Unassigned local variable 'strX'
            }
        }

我尝试通过遍历 List 的副本来使用 do/while 语句,但也没有用。

编辑

文本文件中的数据是这样的..

^<a class= ........>Name</a>
value1
value2
value3
value4
etc....
^<a class=......>Name</a>
value1
value2
value3
value4
etc....
^<a class=......>Name</a>
etc...

我想要完成的事情

name, value1, value2, value3, value4, etc...
name, value1, value2, value3, value4, etc...

编辑 结果为 csv。

在您看到链接的地方,它前面有一个 ^,当到达该链接时,它应该移动到第 2 行,然后当它再次点击 ^ 到第 3 行,依此类推。当它击中时,它是一个新的记录^

这应该是它的样子......

编辑/更新

Physician Name, (CPSO#)
Primary Practice Location
Disciplinary Info  &amp; Restrictions
^Aal Ali, Saleh Saif Salem A S Fares (#82358)
P O Box: 8313
Abu Dhabi 0000
United Arab Emirates
Phone: +971506117644
^Aalders, Ryan Francis (#103559)
Kingston General Hospital
Department of Family Medicine
76 Stuart Street
Kingston ON  K7L 2V7
Phone: (613) 533-9300
^Aarabi, Mehdi (#81281)
UHN Toronto Western Hospital
2nd Floor East Wing
399 Bathurst Street
Toronto ON  M5T 2S8
Phone: (416) 603-5641
^Aaron, Shawn David (#62311)
Ottawa General Hospital
501 Smyth Road
Ottawa ON  K1H 8L6
Phone: (613) 737-8899 Ext. 74729
Fax: (613) 739-6807

【问题讨论】:

  • 什么是lstData?是包含a,b^c,d 的字符串吗?你想分裂^ 然后,?转义字符有什么注意事项吗?你想要的只是lstData.Split('^').Select(x =&gt; x.Split(',')).ToArray()?即返回一个字符串数组的数组,其中每个数组包含一个逗号分隔字段的数组?
  • @KirkWoll,对不起,是的 lstData 是我放入 List 的文本文件数据。文本文件数据不是逗号分隔的,每个值都在一个新行上。我正在获取数据并将其添加到字符串生成器并分离它。
  • 所以你只想要x.Split(^)?抱歉,我会把它作为答案发布,但我仍然不能 100% 满足您的要求。
  • @KirkWoll,我将编辑问题并更具体...
  • string.Join 有什么问题?

标签: c# if-statement foreach


【解决方案1】:

作为替代方案,您可以使用 LINQ 来构建列表。请参阅以下内容: Make CSV from list of string in LINQ

【讨论】:

  • 我搜索了很多链接并错过了那个
【解决方案2】:

您可以创建一个辅助方法,在遇到胡萝卜时添加换行符。 File.ReadLine 将在换行符处中断,然后我们可以替换辅助方法中的胡萝卜并进行您想要的数据清理。然后使用 String.Join 将所有结果用逗号组合回来。

private static void Main(string[] args)
{
    var text = File.ReadLines(@"YourFile.txt");

    var lines = ParseList(text);

    using (var file = File.AppendText(@"NewFile.csv"))
    {
        file.Write(String.Join(",", lines));
    }

    Console.ReadLine();
}

private static IEnumerable<string> ParseList(IEnumerable<string> lines)
{
    foreach (var line in lines)
    {
        var newline = Regex.Replace(line, @"<.*?>", String.Empty);
        if (newline.StartsWith("^"))
        {
            // change carrot to newline
            newline = Environment.NewLine + newline.Remove(0, 1);
        }
        yield return newline;
    }
}

【讨论】:

    【解决方案3】:

    此代码有效,并且还将处理出现在数据中的 ^(作为一行的第一个字符除外)

    var text = File.ReadAllText("filename.txt");
    using(var file = File.AppendText("NewFile.txt"))
    foreach (var csv in text.Split(new []{Environment.NewLine+"^", "\n^"}, StringSplitOptions.None)
        .Select(line => line.Split(new []{Environment.NewLine, "\n"}, StringSplitOptions.None))
        .Select(sublines => string.Join(",", sublines.Select(s => s.ToString()))))
    {
        file.WriteLine(csv);
    }
    

    看这个小提琴:

    https://dotnetfiddle.net/uyHppL

    而且,这是一个不使用 foreach 的变体,它应该更高效一些,因为它只写入文件一次。

    var csv = string.Join(Environment.NewLine, text.Split(new []{Environment.NewLine+"^", "\n^"}, StringSplitOptions.None)
        .Select(line => line.Split(new []{Environment.NewLine, "\n"}, StringSplitOptions.None))
        .Select(sublines => string.Join(",", sublines.Select(s => s.ToString()))));
    
    using(var file = File.AppendText("NewFile.txt"))
        file.WriteLine(csv);
    

    【讨论】:

    • 这很接近,它在 ^ 处将其分开,但在它下方是值并且不像我添加的图片那样看起来像,我知道它没有经过测试:)
    • @Chris - 什么?我不明白你的意思
    • @Chris - 由于您没有向我们展示实际数据是什么,我们只能猜测,您必须做出与我们猜测不同的任何更改。我的代码假设每一行都以 \r\n 结尾,如果它只是 \n 则需要更改为该行。以文本形式向我们展示 ACTUAL csv(不是电子表格中的数据)并确认行尾类型。
    • 我确实展示了数据的样子,它在上面的编辑中。 Noctis 和 emodendroket cmets 和解决方案,将其放入 csv 文件(它在第一张图片中,您可以在一行中看到所有内容),第二张图片是我试图让它看起来的样子。
    • @Chris - 您的第一列中还有嵌入逗号的问题。因此,您必须在该列周围加上引号,以便 Excel 将其加载到单个单元格中。
    【解决方案4】:

    这似乎有效:

    List<string> list = 
        new List<string>{"^one","two","^three","four","f1","f2","^five","six","s1","s2"};
    
    StringBuilder sb = new StringBuilder();
    foreach (var element in list)
    {
        if (element.Contains("^")) {
            sb.Append("\r\n" + element.Replace("^",""));
        }
        else  {
            sb.Append("," + element);
        }
    }
    var result = sb.ToString();
    

    它输出:

    一,二
    三、四、f1、f2
    五、六、s1、s2

    您可能希望在其中进行 html 解析

    【讨论】:

    • 当我运行它并将结果保存到 csv 文件时,所有数据都被分成单元格,但它们都在第 1 行,并在第 2 行、第 3 行等两行移动。 .当它击中下一个^
    • 当我打开它时,我将编辑并添加一张结果图片...^ 是一个分隔符,当它被击中时,它就是一个新记录的开始,应该在第 2 行, 第 3 行等.. 一秒
    • 我刚刚添加了一张我试图让它看起来如何的新照片
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-17
    • 1970-01-01
    • 2021-12-22
    • 1970-01-01
    • 2021-01-13
    • 1970-01-01
    相关资源
    最近更新 更多