【问题标题】:CSV row split into string array questionCSV 行拆分为字符串数组问题
【发布时间】:2010-08-21 14:10:29
【问题描述】:

您将如何将此行拆分为字符串数组

问题是 Rutois, a.s. , 所以不能直接用','分隔符..

543472,"36743721","Rutois, a.s.","151","some name","01341",55,"112",1

谢谢

【问题讨论】:

标签: c# string split


【解决方案1】:

我建议您使用 CSV 解析器而不是 rolling your own

FileHelpers 是适合这项工作的一个不错的库。

【讨论】:

  • 它实际上是一个非常简单的有限状态机。几年前我写了一个,因为 ADO 觉得这个任务有点过头了。
  • +1。 codeproject.com/KB/database/CsvReader.aspx 是一个不错的轻量级。 @liho1eye:这可能很简单,但重新发明轮子并不能为您的客户创造价值。
  • @TrueWill 这有点循环逻辑。此外,我只是查看了您的链接,这似乎与我的解决方案几乎相同……可能要抛光得多,但(查看修订日志)比我的至少年轻 2 年。并不是说我试图声明对此实现的权利。它只是证明 CSV 解析器很容易制作。
  • @liho1eye:如果您有替代实现,那太好了!将其发布为开源(如果您拥有版权)并让其他人从您的努力中受益。我要说的是,除了(a)作为学习练习,(b)他们的平台上没有可用的,或者(c)现有的解析器不满足他们的业务之外,其他人没有理由编写 CSV 解析器要求。
【解决方案2】:

您可以使用正则表达式从该行中挑选出值:

string line ="543472,\"36743721\",\"Rutois, a.s.\",\"151\",\"some name\",\"01341\",55,\"112\",1";
var values = Regex.Matches(line, "(?:\"(?<m>[^\"]*)\")|(?<m>[^,]+)");
foreach (Match value in values) {
  Console.WriteLine(value.Groups["m"].Value);
}

输出:

543472
36743721
Rutois, a.s.
151
some name
01341
55
112
1

这当然假设您实际上已经在字符串中获得了完整的 CSV 记录。请注意,CSV 记录中的值可以包含换行符,因此无法通过简单地在换行符处拆分来从 CSV 文件中获取记录。

【讨论】:

  • 我检查了你的正则表达式,在这种情况下它失败了:"text1,\"text2,\"text3" 它应该返回值:text1 | "text2 | "text3 但它返回:text1 |文本2,|文本3
  • @Bronek:你认为它为什么应该这样做?
  • ...'因为它不应该在第二个引号之后划分此数据。在这种情况下,逗号被假定为分隔符。
  • @Bronek:该输入无效,因此未定义预期结果。
【解决方案3】:

你可以使用 odbc 连接到文件检查这个

link(如果链接没有多大帮助,只需谷歌它“将 csv 文件与 odbc 连接”)

如果您在 odbc 中遇到问题,我猜该文件不是有效的 csv 文件。

【讨论】:

【解决方案4】:

我很想换掉引号字符串中出现的引号,然后使用拆分。这会起作用。

        string csv = "543472,\"36743721\",\"Rutois, a.s.\",\"151\",\"some name\",\"01341\",55,\"112\",1"; 


        const string COMMA_TOKEN = "[COMMA]";
        string[] values;
        bool inQuotes = false;

        StringBuilder cleanedCsv = new StringBuilder();
        foreach (char c in csv)
        {
            if (c == '\"')
                inQuotes = !inQuotes;  //work out if inside a quoted string or not
            else
            {
                //Replace commas in quotes with a token
                if (inQuotes && c == ',')
                    cleanedCsv.Append(COMMA_TOKEN);
                else
                    cleanedCsv.Append(c);
            }
        }

        values = cleanedCsv.ToString().Split(',');

        //Put the commas back
        for (int i = 0; i < values.Length; i++)
            values[i] = values[i].Replace(COMMA_TOKEN, ",");

【讨论】:

  • 我已经检查了您的解决方案,但在这种情况下它失败了:"text1,\"text2,\"text3" 它应该返回值:text1 | "text2 | "text3 但它返回:text1 |文本2,文本3
  • 上面的代码虽然在使用非成对双引号的情况下没有用,但对我很有帮助,它允许我读取 30 多个不同文件格式的文本文件,有时双引号中有逗号。我能够正确解析字段,然后使用 EPPlus 创建 excel 文件。我必须添加的一件事是,当列在数字列中包含前导零时,删除字段开头的等号以保留额外的零,例如="00003322"。
【解决方案5】:

我猜你想要这样的东西 -

string csv = 543472,"36743721","Rutois, a.s.","151","some name","01341",55,"112",1 ;
string[] values;
values = csv.Split(",");
for(int i = 0; i<values.Length; i++)
{
    values[i] = values[i].Replace("\"", "");
}

希望这会有所帮助。

【讨论】:

  • 除了你要将值内的所有逗号拆分为
  • 如何检查这是否有效? Console.WriteLine(values);?
【解决方案6】:

如果第一个字符是引号,则其他 RegEx 答案将失败。

这是正确的正则表达式:

string[] columns = Regex.Split(inputRow, ",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-24
    • 2016-04-01
    • 2010-10-31
    • 1970-01-01
    相关资源
    最近更新 更多