一尘不染

用带引号和不带引号的字符串分割逗号分隔的字符串[重复]

c#

这个问题已经在这里有了答案

如何拆分其列可能包含的csv, (8个答案)

2年前关闭。

我需要分割以下逗号分隔的字符串。问题在于某些内容包含在引号中,并且包含不应该在拆分中使用的逗号。

串:

111,222,"33,44,55",666,"77,88","99"

我想要输出:

111  
222  
33,44,55  
666  
77,88  
99

我已经试过了:

(?:,?)((?<=")[^"]+(?=")|[^",]+)

但是它读取“ 77,88”,“ 99”之间的逗号作为命中,并且我得到以下输出:

111  
222  
33,44,55  
666  
77,88  
,  
99

阅读 265

收藏
2020-05-19

共1个答案

一尘不染

根据您的需求,您可能无法使用csv解析器,并且实际上可能想重新发明轮子!

您可以使用一些简单的正则表达式来实现

(?:^|,)(\"(?:[^\"]+|\"\")*\"|[^,]*)

这将执行以下操作:

(?:^|,)=匹配表达式“行或字符串的开头,

(\"(?:[^\"]+|\"\")*\"|[^,]*) =一个编号的捕获组,它将在2个备选方案之间进行选择:

  1. 引号中的东西
  2. 逗号之间的内容

这应该为您提供所需的输出。

C#中的示例代码

 static Regex csvSplit = new Regex("(?:^|,)(\"(?:[^\"]+|\"\")*\"|[^,]*)", RegexOptions.Compiled);

public static string[] SplitCSV(string input)
{

  List<string> list = new List<string>();
  string curr = null;
  foreach (Match match in csvSplit.Matches(input))
  {        
    curr = match.Value;
    if (0 == curr.Length)
    {
      list.Add("");
    }

    list.Add(curr.TrimStart(','));
  }

  return list.ToArray();
}

private void button1_Click(object sender, RoutedEventArgs e)
{
    Console.WriteLine(SplitCSV("111,222,\"33,44,55\",666,\"77,88\",\"99\""));
}

警告 根据@MrE的评论-
如果流氓换行符出现在格式不正确的csv文件中,并且最终出现不均匀的(“字符串”),您将遭受灾难性的回溯(https://www.regular-
expressions.info/正则表达式中的catastrophic.html)和系统可能会崩溃(就像我们的生产系统一样),可以轻松地在Visual
Studio中复制,并且据我发现会崩溃。简单的try / catch也不会捕获此问题。

您应该使用:

(?:^|,)(\"(?:[^\"])*\"|[^,]*)

代替

2020-05-19